跳转到主要内容

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

项目描述

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

有关安全稳定的元类实用工具,请参阅metautils

模板模型

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

考虑这两个元类。

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 metautils3 import T, templated

class AllLower(T):
    @templated
    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(T):
    @templated
    def __new__(mcls, name, bases, dict_):
        dict_['methods'] = [v for v in dict_.values() if callable(v)];
        return super().__new__(mcls, name, bases, dict_)

Python 2风格的super调用也将工作,例如:super(AllLower, mcls)。我们可以像委托给具体类一样,通过委托给T来编写上述类,例如

from metautils3 import T, templated

 class AllLower(T):
     @templated
     def __new__(mcls, name, bases, dict_):
         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_):
         dict_['methods'] = [v for v in dict_.values() if callable(v)];
         return T.__new__(mcls, name, bases, dict_)

在模板函数的上下文中,T将指向用于实例化模板实例的具体类。另一个将更替的名字是类名本身。当你在方法的上下文中时,类名实际上会解析为具体类型。

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

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:是否在新的类型对象前添加基本名称。 默认值True

这些可以与任何具体元类一起链式调用,例如

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

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

from metautils3 import compose

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

metautils 的区别

metautils3使用了更多实验性功能,包括字节码和代码对象转换,这允许进行更多隐式的工作。这就是 T 对象如何在方法内部引用模板参数的原因,或者这就是我们如何使 super 正确工作。此包还调用 ctypes 和其他 CPython 特定代码,使其不太便携且难以维护。这主要是一个有趣的证明概念,以推动 metautils 的极限。对于任何生产代码,我必须推荐您使用更稳定的版本。

项目详情


下载文件

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

源分布

metautils3-0.1.2.tar.gz (6.1 kB 查看散列)

上传时间

由以下支持

AWSAWS云计算和安全赞助商 DatadogDatadog监控 FastlyFastlyCDN GoogleGoogle下载分析 MicrosoftMicrosoftPSF 赞助商 PingdomPingdom监控 SentrySentry错误日志 StatusPageStatusPage状态页面