Python __super 黑魔法失败
Python __super black magic failed
我想为元class 创建的每个class 添加一个属性。例如,当创建一个名为 C
的 class 时,我想添加一个属性 C._C__sup
,其值为描述符 super(C)
.
这是我试过的方法:
class Meta(type):
def __init__(cls, name, bases, dict): # Not overriding type.__new__
cls.__dict__['_' + name + '__sup'] = super(cls)
# Not calling type.__init__; do I need it?
class C(object):
__metaclass__ = Meta
c = C()
print c._C__sup
这给了我:
TypeError: Error when calling the metaclass bases
'dictproxy' object does not support item assignment
一些背景信息:
(您不必阅读此部分)
受到this article的启发,我正在做的是在使用super
时尽量避免"hardcoding" class名称:
The idea there is to use the unbound super objects as private
attributes. For instance, in our example, we could define the private
attribute __sup
in the class C
as the unbound super object
super(C)
:
>>> C._C__sup = super(C)
With this definition inside the methods the syntax self.__sup.meth
can be used as an alternative to super(C, self).meth
. The advantage
is that you avoid to repeat the name of the class in the calling
syntax, since that name is hidden in the mangling mechanism of private
names. The creation of the __sup
attributes can be hidden in a
metaclass and made automatic. So, all this seems to work: but
actually this not the case.
使用 setattr
而不是赋值给 cls.__dict__
:
class Meta(type):
def __init__(cls, name, bases, clsdict): # Not overriding type.__new__
setattr(cls, '_' + name + '__sup', super(cls))
super(Meta, cls).__init__(name, bases, clsdict)
class C(object):
__metaclass__ = Meta
def say(self):
return 'wow'
class D(C):
def say(self):
return 'bow' + self.__sup.say()
c = C()
print(c._C__sup)
# <super: <class 'C'>, <C object>>
d = D()
print(d.say())
打印
bowwow
顺便说一句,打电话是个好主意
super(Meta, cls).__init__(name, bases, clsdict)
在 Meta.__init__
中允许 Meta
参与 class 层次结构
可能需要 super
才能正确调用 __init__
链。这似乎
特别合适,因为您正在构建一个 metaclass 来协助
使用 super
.
我想为元class 创建的每个class 添加一个属性。例如,当创建一个名为 C
的 class 时,我想添加一个属性 C._C__sup
,其值为描述符 super(C)
.
这是我试过的方法:
class Meta(type):
def __init__(cls, name, bases, dict): # Not overriding type.__new__
cls.__dict__['_' + name + '__sup'] = super(cls)
# Not calling type.__init__; do I need it?
class C(object):
__metaclass__ = Meta
c = C()
print c._C__sup
这给了我:
TypeError: Error when calling the metaclass bases
'dictproxy' object does not support item assignment
一些背景信息:
(您不必阅读此部分)
受到this article的启发,我正在做的是在使用super
时尽量避免"hardcoding" class名称:
The idea there is to use the unbound super objects as private attributes. For instance, in our example, we could define the private attribute
__sup
in the classC
as the unbound super objectsuper(C)
:>>> C._C__sup = super(C)
With this definition inside the methods the syntax
self.__sup.meth
can be used as an alternative tosuper(C, self).meth
. The advantage is that you avoid to repeat the name of the class in the calling syntax, since that name is hidden in the mangling mechanism of private names. The creation of the__sup
attributes can be hidden in a metaclass and made automatic. So, all this seems to work: but actually this not the case.
使用 setattr
而不是赋值给 cls.__dict__
:
class Meta(type):
def __init__(cls, name, bases, clsdict): # Not overriding type.__new__
setattr(cls, '_' + name + '__sup', super(cls))
super(Meta, cls).__init__(name, bases, clsdict)
class C(object):
__metaclass__ = Meta
def say(self):
return 'wow'
class D(C):
def say(self):
return 'bow' + self.__sup.say()
c = C()
print(c._C__sup)
# <super: <class 'C'>, <C object>>
d = D()
print(d.say())
打印
bowwow
顺便说一句,打电话是个好主意
super(Meta, cls).__init__(name, bases, clsdict)
在 Meta.__init__
中允许 Meta
参与 class 层次结构
可能需要 super
才能正确调用 __init__
链。这似乎
特别合适,因为您正在构建一个 metaclass 来协助
使用 super
.