python 元类传递 __init__ 参数
python metaclass pass __init__ params
我正在python3学习元类编程,但遇到了一些问题
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)
此代码可以将所有属性大写。
我想给init传递一个参数,但是当我运行这段代码的时候,提示出错
TypeError: object() takes no parameters
我该如何解决这个问题?
您正在过滤掉 __init__
方法:
attrs = ((name, value) for name, value in class_attr.items() if not
name.startswith('__'))
attrs
是所有不以__
开头的属性。然后将 attrs
大写并将其用于您创建的 class,因此 __init__
从未用于新的 class。因为得到的Bar
class没有__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()
的0参形式,毕竟这是Python3
现在 metaclass 可以正常工作并且 Base.__init__
存在:
>>> sorted(vars(Base))
['BAR', '__dict__', '__doc__', '__init__', '__module__', '__weakref__']
>>> t = Base(1)
>>> t.BAR
12
>>> t.params
1
我正在python3学习元类编程,但遇到了一些问题
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)
此代码可以将所有属性大写。
我想给init传递一个参数,但是当我运行这段代码的时候,提示出错
TypeError: object() takes no parameters
我该如何解决这个问题?
您正在过滤掉 __init__
方法:
attrs = ((name, value) for name, value in class_attr.items() if not
name.startswith('__'))
attrs
是所有不以__
开头的属性。然后将 attrs
大写并将其用于您创建的 class,因此 __init__
从未用于新的 class。因为得到的Bar
class没有__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()
的0参形式,毕竟这是Python3
现在 metaclass 可以正常工作并且 Base.__init__
存在:
>>> sorted(vars(Base))
['BAR', '__dict__', '__doc__', '__init__', '__module__', '__weakref__']
>>> t = Base(1)
>>> t.BAR
12
>>> t.params
1