python元类传递__init__ params

时间:2018-03-02 09:41:19

标签: python init metaclass

我在python 3中学习元类编程,但我遇到了一些问题

class UpperAttrMetaClass(type): # to uppercase all attrs
    def __new__(mcs, class_name, class_parents, class_attr):
        attrs = ((name, value) for name, value in class_attr.items() if not 
            name.startswith('__'))
        uppercase_attrs = dict((name.upper(), value) for name, value in attrs)
        return super(UpperAttrMetaClass, mcs).__new__(mcs, class_name, 
                     class_parents, uppercase_attrs)

class Base(metaclass=UpperAttrMetaClass):
    bar = 12
    def __init__(self, params):
        super(Base, self).__init__()
        self.params = params

t = Base(1)
print(t.BAR)
print(t.params)

此代码可以大写所有attrs。

我想将参数传递给 init ,但是当我运行此代码时,我提示错误

TypeError: object() takes no parameters

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您正在过滤掉attrs = ((name, value) for name, value in class_attr.items() if not name.startswith('__')) 方法:

attrs

__是所有不以attrs开头的属性。然后,您将__init__大写,并将其用于您创建的类,因此Bar 从未用于新类。由于生成的__init__类没有object.__init__方法,因此使用>>> sorted(vars(Base)) ['BAR', '__dict__', '__doc__', '__module__', '__weakref__'] >>> Base.__init__ <slot wrapper '__init__' of 'object' objects> ,并且该方法不接受参数:

__

包含所有属性,请勿过滤,但仅限大写不包含class UpperAttrMetaClass(type): # to uppercase all attrs def __new__(mcs, class_name, class_parents, class_attr): attrs = {name if name.startswith('__') else name.upper(): value for name, value in class_attr.items()} return super().__new__(mcs, class_name, class_parents, attrs) 的属性:

name if name.startswith('__') else name.upper()

我在这里使用字典理解;请注意__条件表达式,当名称不以super()开头时,它会生成大写的属性名称。

我还使用了Base.__init__的0参数形式,毕竟这是Python 3。

现在元类工作正常,>>> sorted(vars(Base)) ['BAR', '__dict__', '__doc__', '__init__', '__module__', '__weakref__'] >>> t = Base(1) >>> t.BAR 12 >>> t.params 1 存在:

DateTime