模块级的python元类
我读 我尝试复制示例中的上层元类,发现这并不是在所有情况下都有效:模块级的python元类,python,python-3.x,metaclass,Python,Python 3.x,Metaclass,我读 我尝试复制示例中的上层元类,发现这并不是在所有情况下都有效: def upper(cls_name, cls_parents, cls_attr): """ Make all class attributes uppper case """ attrs = ((name, value) for name, value in cls_attr
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中的所有类都已经将object作为它们的父类,元类解析进入object类
问题:
如何在python3中创建模块级元类?如果您想将所有属性都更改为大写,您可能应该使用
\uuuu init\uuuu
方法来实现这一点,而不是使用元类
元类比99%的用户应该担心的更神奇。如果你想知道你是否需要它们,你不需要(真正需要它们的人肯定知道他们需要它们,也不需要解释原因)
--巨蟒大师
如果你需要更深入的东西,你也应该评估使用
只要您想做一些可以使用类装饰器或初始化的事情,那么使用元类和理解类是如何创建的就没有必要了
也就是说,如果你真的想使用一个元类,把它作为关键字参数传递给这个类
class Foo(object, metaclass=UpperCaseMetaClass)
其中,UpperCaseMetClass
是扩展类型的类,而不是方法
class UpperCaseMetaClass(type):
def __new__():
#Do your Magic here.
模块级元类不是真正的“模块级”,它与类初始化的工作方式有关。在创建类时,类创建将查找变量“\uuuuu元类”
,如果它不在本地环境中,则将查找全局。因此,如果您有一个“模块级”\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
在Python3中,在类定义中使用metaclass=
指定元类。因此,没有模块级元类
那你是做什么的?简单:为每个类显式指定它
这真的不需要太多额外的工作,如果你真的有数百个类并且不想手动执行,你甚至可以通过一个很好的regexp搜索和替换来完成。也许你需要的是一个类装饰器而不是一个元类。@Sven Marnach:\uuuuuuuuuuuuuuuuuuuuuuuuuuuuu确实可能绑定到一个函数。该函数只需要接受与元类“\uuuu init\uuuu()
方法相同的参数,并返回一个类型对象。@Sven Marnach:需要接受与元类“\uuu init\uuuuu()方法相同的参数-除了self
,也就是说。@pillmuncher:你基本上是对的,除了它的参数与元类“\uuuu new\uuu()
方法相同之外。我没有意识到这一点,尽管事实上很明显,任何可调用的都可以。(请注意,可调用对象甚至不必返回类型对象。可调用对象返回的任何对象都将绑定到类名。)那么,python3与模块级元类的等价物是什么?似乎还没有人回答你的实际问题。该功能是否已被废弃?好奇的人想知道。谢谢!这非常有帮助。蒂姆·彼得斯的联系中断了;这是一个存档版本:我建议您使用模块范围的超类,例如类基类(object,metaclass=upper):pass
然后将所有相关类基于这个基类。