带有继承的Python __new__元类行为 [英] Python __new__ metaclass behavior with inheritance
问题描述
关于运行以下代码的行为,我有两个问题.为什么甚至在不实例化对象的情况下调用__new__
?我以为__new__
控制着新 instance 的创建.接下来,为什么当hasattr
返回 size 的 True 时,delattr
为什么会引发 AttributeError ?
I have two questions regarding the behavior of running the below code. Why is __new__
even being called without instantiating an object? I thought __new__
controlled the creation of a new instance. Next, why does delattr
raise an AttributeError when hasattr
returns True for size?
class ShapeBase(type):
def __new__(cls, name, bases, attrs):
rv = super(ShapeBase, cls).__new__(cls, name, bases, attrs)
parents = [base for base in bases if isinstance(base, ShapeBase)]
# don't do anything unless this is a subclass of Shape
if not parents:
return rv
print hasattr(rv, 'altitude') # prints True
print rv.altitude # prints 7
del rv.altitude # deletes altitude from rv
print hasattr(rv, 'size') # prints True
print rv.size # prints 5
delattr(rv, 'size') # raises AttributeError
return rv
class Shape(object):
__metaclass__ = ShapeBase
size = 5
class Triangle(Shape):
altitude = 7
推荐答案
对于第二个问题,delattr(rv, 'size')
(和del rv.size
)失败了,因为属性size
是类属性,而不是实例属性,意味着部分类__dict__
而不是实例__dict__
.
For the second question delattr(rv, 'size')
(and del rv.size
) is failing because the attribute size
is a class attribute not an instance attribute which mean is part of the class __dict__
not the instance __dict__
.
hasattr
通常会返回True
,因为它会在传递给它的对象的所有父类中搜索一个属性.
And the hasattr
normally will return True
because it search for an attribute in all the parent classes of the object passed to it.
关于为什么在评估类主体时调用元类__new__
的原因是这样的:
As for why your metaclass __new__
is called when the class body is evaluated think of it like this :
如果创建类的实例,则在创建实例时将调用类
__new__
,是吗?因此对class来说也应如此,元类是类的类,因此在创建类时将调用__new__
.
If you create an instance of a class the class
__new__
will be called when you create the instance, yes ? so the same should apply on class , a metaclass is a class of a class so the__new__
will be called when you create the class.
这篇关于带有继承的Python __new__元类行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!