当使用 __new__ 自定义元类的创建时,我们可以将属性传递给 type().__new__ 方法,该方法将在对象返回之前对其进行设置,例如
class Foo(type):
def __new__(cls, name, bases, attrs):
attrs['customAttr'] = 'someVal'
return type.__new__(cls, name, bases, attrs)
以便:
>> Foo.__dict__
{'customeAttr': 'someVal', ...}
但是我不知道如何对普通(非元)类做同样的事情,这在使用 __setattr__ 时会导致问题:
class Bar(object):
def __new__(cls, someVal):
obj = object().__new__(cls) # cant pass custom attrs
obj.customAttr = someVal # obj is already a Bar and invokes __setattr__
return obj
def __setattr__(*args): raise Exception('read-only class')
所以不幸的是:
>>> Bar(42)
...
Exception: read-only class
在 Bar 的 __new__ 中,我从 object() 中获取了一个完全成熟的类实例,并且任何属性访问都通过正常的查找规则,在这种情况下调用 __setattr__。元类 Foo 避免了这种情况,因为 type() 将在低级创建期间返回实例之前设置属性,而 object() 不会。
有没有办法将属性传递给 object() 或者是另一种我可以用作从 __new__ 返回的实例的另一种类型,它允许在属性成为完整的类实例之前设置属性?我对在实例创建后设置 __class__ 之类的解决方案不感兴趣。