- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个关于元类的奇怪和不寻常的用例,我想在基类被定义后更改 __metaclass__
,以便它的子类将自动使用新的 __metaclass__
。但这奇怪地不起作用:
class MetaBase(type):
def __new__(cls, name, bases, attrs):
attrs["y"] = attrs["x"] + 1
return type.__new__(cls, name, bases, attrs)
class Foo(object):
__metaclass__ = MetaBase
x = 5
print (Foo.x, Foo.y) # prints (5, 6) as expected
class MetaSub(MetaBase):
def __new__(cls, name, bases, attrs):
attrs["x"] = 11
return MetaBase.__new__(cls, name, bases, attrs)
Foo.__metaclass__ = MetaSub
class Bar(Foo):
pass
print(Bar.x, Bar.y) # prints (5, 6) instead of (11, 12)
我正在做的事情很可能是不明智的/不受支持的/未定义的,但我终其一生都无法弄清楚旧的元类是如何被调用的,我想至少了解这是怎么可能的。
编辑: 根据 jsbueno
的建议,我将 Foo.__metaclass__ = MetaSub
行替换为以下行,这确实正是我想要的:
Foo = type.__new__(MetaSub, "Foo", Foo.__bases__, dict(Foo.__dict__))
最佳答案
问题是继承时未使用 __metaclass__
属性,这与您的预期相反。也不会为 Bar
调用“旧”元类。文档说明了如何找到元类:
The appropriate metaclass is determined by the following precedence rules:
- If dict['__metaclass__'] exists, it is used.
- Otherwise, if there is at least one base class, its metaclass is used (this looks for a __class__ attribute first and if not found, uses its type).
- Otherwise, if a global variable named __metaclass__ exists, it is used.
- Otherwise, the old-style, classic metaclass (types.ClassType) is used.
所以在您的 Bar
类中实际用作元类的是在父级的 __class__
属性中找到的,而不是在父级的 __metaclass__
属性中。
更多信息可以在 this StackOverflow answer 上找到.
关于python - 为什么我不能更改类的 __metaclass__ 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8867029/
编辑:请注意,在生产代码中这样做是一个非常糟糕的想法。这对我来说只是一件有趣的事情。不要在家里这样做! 是否可以在 Python 中为整个程序(解释器)修改 __metaclass__ 变量? 这个简
元类 向类添加无效属性? 这是我的代码: def __metaclass__(clsname, bases, dct): dct["key1"] = "value1" dct["inv
我的问题是我正在使用元类将某些类方法包装在计时器中以用于日志记录。 例如: class MyMeta(type): @staticmethod def time_method(meth
在阅读了部分Django源代码后,我想在下面做一些测试和编写代码,看看元类是如何工作的: class MyMeta(type): def __new__(cls, name, bases, a
我有一个关于元类的奇怪和不寻常的用例,我想在基类被定义后更改 __metaclass__,以便它的子类将自动使用新的 __metaclass__ 。但这奇怪地不起作用: class MetaBase(
Python(仅限 2?)查看变量 __metaclass__ 的值以确定如何从类定义创建 type 对象。 It is possible to define __metaclass__ at the
要创建动态类变量,您似乎有两种选择 - 使用 locals() 或 __metaclass__。我不喜欢分配给 locals() 但它似乎在类定义中工作并且比它的 __metaclass__ 替代方案
类属性 __metaclass__ 和类关键字参数 metaclass 有什么区别。 考虑这个例子: class Meta1(type): def __new__(cls, name, bas
我有一个用于行数据的元类。任何记录都应该是此类固有的,因此您可以在下面看到我尝试固有两次,一次用于程序,一次用于 Assets 。但是我需要将 OrderedDict 传递给元类,或者将插槽和初始化函
我想重新定义一个 __metaclass__ 但我想回退到如果我没有重新定义就会使用的元类。 class ComponentMetaClass(type): def __new__(cls,
我一直在努力学习 Python 中的元类。我明白了主要思想,但我似乎无法激活该机制。据我了解,您可以在构造类 K 时指定 M 作为元类,方法是在全局或类级别将 __metaclass__ 设置为 M。
在 Python2.7 中,这段代码可以很好地工作, __getattr__ in MetaTable会跑。但在 Python 3 中它不起作用。 class MetaTable(type):
我只是在尝试 neo4django 的 very own example , 即 from neo4django.db import models class Person(models.NodeMo
前段时间,作为学习Python+Django过程的一部分,我决定为BIT列类型编写一个自定义的MySQL特定的模型字段。不幸的是,我遇到了一个问题。 项目:包含一个“主”应用 “主”应用程序:包含由“
protobuf 生成 C++/Java 类,这些是静态类型的类,足以进行编码/解码。为什么它生成具有 metaclass 属性的 python 类:我想普通类就足以进行 rpc,就像 C++/Jav
我是一名优秀的程序员,十分优秀!