我在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
我该如何解决这个问题?
答案 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