模块级别的 python 元类
我读过 Python 中的元类是什么?
我尝试了复制示例中的上元类,发现这在所有情况下都不起作用:
def upper(cls_name, cls_parents, cls_attr):
""" Make all class attributes uppper case """
attrs = ((name, value) for name, value in cls_attr.items()
if not name.startswith('__'))
upper_atts = dict((name.upper(), value) for name, value in attrs)
return type(cls_name, cls_parents, upper_atts)
__metaclass__ = upper #Module level
class Foo:
bar = 1
f = Foo()
print(f.BAR) #works in python2.6
上面在 python3 中失败(带有属性错误),我认为这是自然的,因为 python3 中的所有类都已经将对象作为它们的对象父类和元类解析进入对象类。
问题:
如何在 python3 中创建模块级元类?
I read What is a metaclass in Python?
and I tried to replicate the upper metaclass from the example and found that this doesn't work in all cases:
def upper(cls_name, cls_parents, cls_attr):
""" Make all class attributes uppper case """
attrs = ((name, value) for name, value in cls_attr.items()
if not name.startswith('__'))
upper_atts = dict((name.upper(), value) for name, value in attrs)
return type(cls_name, cls_parents, upper_atts)
__metaclass__ = upper #Module level
class Foo:
bar = 1
f = Foo()
print(f.BAR) #works in python2.6
The above fails (with an attribute error) in python3 which I think is natural because all classes in python3 already have object as their parent and metaclass resolution goes into the object class.
The question:
How do I make a module level metaclass in python3?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
模块级元类并不是真正的“模块级”,它与类初始化的工作方式有关。创建类时,类创建将查找变量
“__metaclass__”
,如果它不在本地环境中,它将在全局环境中查找。因此,如果您有一个“模块级别”__metaclass__
,它将用于以后的每个类,除非它们具有显式元类。在 Python 3 中,您可以在类定义中使用
metaclass=
指定元类。因此没有模块级元类。那你怎么办?简单:为每个类明确指定它。
这实际上并没有太多额外的工作,如果您确实有数百个类并且不想手动执行,您甚至可以通过良好的正则表达式搜索和替换来完成。
The module level metaclass isn't really "module level", it has to do with how class initialization worked. The class creation would look for the variable
"__metaclass__"
when creating the class, and if it wasn't in the local environment it would look in the global. Hence, if you had a "module level"__metaclass__
that would be used for every class afterwards, unless they had explicit metaclasses.In Python 3, you instead specify the metaclass with a
metaclass=
in the class definition. Hence there is no module level metaclasses.So what do you do? Easy: You specify it explicitly for each class.
It's really not much extra work, and you can even do it with a nice regexp search and replace if you really have hundreds of classes and don't want to do it manually.
如果您想将所有属性更改为大写,您可能应该使用 __init__ 方法来执行此操作,而不是使用元类。
如果您需要一些东西更深入地说,您还应该使用类装饰器进行评估。
只要您想做一些可以使用类装饰器或初始化来完成的事情,那么使用元类并了解如何创建类是不必要的。
也就是说,如果您确实想使用元类,请将其作为关键字参数传递给该类。
其中
UpperCaseMetaClass
是扩展type
的类,而不是方法。If you want to change all the attributes to upper case, you should probably use the
__init__
method to do so, than use a metaclass.If you need something deeper, you should also evaluate using Class Decorators.
Using MetaClasses and understanding how the classes are created is so unnecessary as long as you want to do something that you can do using class decorators or initialization.
That said, if you really want to use a Metaclass tho' pass that as a keyword argument to the class.
where
UpperCaseMetaClass
is a class that extendstype
and not a method.