跳转到主要内容

用于与元类一起工作的工具。

项目描述

用于编写和组合元类的工具。

模板模型

为什么我们需要或想要编写类模板。

考虑这两个元类。

class AllLower(type):
    def __new__(mcls, name, bases, dict_):
        dict_ = {k.lower(): v for k, v in dict_.items()}
        return super().__new__(mcls, name, bases, dict_)


class MethodCatcher(type):
    def __new__(mcls, name, bases, dict_):
        dict_['methods'] = [v for v in dict_.values() if callable(v)]
        return super().__new__(mcls, name, bases, dict_)

如果我们想创建一个使用这两个元类的类,我们会怎么做?使用同时继承AllLowerMethodCatcher的类不起作用,我们想要的是一种链式方法。

在类模板模型中,我们可以这样编写我们的元类:

from metautils import T, templated

class AllLower(T):
    @templated
    def __new__(mcls, name, bases, dict_, T_):
        dict_ = {k.lower(): v for k, v in dict_.items()}
        return T_.__new__(mcls, name, bases, dict_)


class MethodCatcher(T):
    @templated
    def __new__(mcls, name, bases, dict_, T_):
        dict_['methods'] = [v for v in dict_.values() if callable(v)];
        return T_.__new__(mcls, name, bases, dict_)

现在我们可以定义同时使用这两个元类的类,如下所示

class C(object, metaclass=MethodCatcher(AllLower())):
    def F():
        pass

    def g():
        pass

    a = 'a'
    B = 'b'

我们可以看到这应用了元类的组合。

>>> C.f
<function __main__.C.F>
>>> C.g
<function __main__.C.g>
>>> C.b
'b'
>>> C.a
'a'
>>> C.methods
[<function __main__.C.g>, <function __main__.C.F>]

元类组合的顺序是明确的,因为它们作为彼此的转换器。

模板

虽然前面的例子只显示了元类,但你可以将此用于任何类;然而,它对于元类来说最有用,其中兼容的元类层次结构很重要。

一个 模板 是一个可调用的对象,它接受一个 类型 对象并返回一个新的 类型 对象。它接受以下参数

  • base: 一个类型对象。 默认值: type

  • adjust_name: 是否将 base 的名称添加到新的类型对象之前。 默认值: True

这些可以与任何末尾的具体元类链接起来,例如:

new_class = m(n,p(q(...z(type)...)))

您还可以使用组合函数来完成此操作

from metautils import compose

new_class_template = compose(m, n, p, q, ..., z)

项目详情


下载文件

下载您平台对应的文件。如果您不确定该选择哪个,请了解更多关于 安装包 的信息。

源分发

metautils-0.1.2.tar.gz (8.6 kB 查看哈希值)

上传时间

支持