带有继承的Python __new__元类行为 [英] Python __new__ metaclass behavior with inheritance

查看:248
本文介绍了带有继承的Python __new__元类行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于运行以下代码的行为,我有两个问题.为什么甚至在不实例化对象的情况下调用__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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆