Python set attributes during object creation in __new__
当使用uuu new_uuu自定义元类的创建时,我们可以将属性传递给type()方法,该方法将在返回对象之前对其进行设置,例如。
1 2 3 4 | class Foo(type): def __new__(cls, name, bases, attrs): attrs['customAttr'] = 'someVal' return type.__new__(cls, name, bases, attrs) |
以便:
1 2 | >> Foo.__dict__ {'customeAttr': 'someVal', ...} |
但是,我不知道如何对普通(非元)类执行相同的操作,这会在使用uu setattr_uuuuuu时导致问题:
1 2 3 4 5 6 7 | 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') |
不幸的是:
1 2 3 | >>> Bar(42) ... Exception: read-only class |
在uuu new_uuuuuo的bar中,我从object()中得到一个完全成熟的类实例,任何属性访问都会通过正常的查找规则,在本例中调用uu setattr_uuuu。元类foo避免了这一点,因为type()将在低级创建期间返回实例之前设置属性,而object()则不会。
有没有一种方法可以将属性传递给object()或者我可以使用另一种类型作为从新返回的实例,它允许在属性成为完整类实例之前设置属性?我对解决方案不感兴趣,比如在创建实例后设置类。
您必须通过调用
1 | obj.customAttr = someVal |
到:
1 | object.__setattr__(obj, 'customAttr', someVal) |
一种不太一般的方法(不适用于基于
1 | obj.__dict__['customAttr'] = someVal # Equivalently: vars(obj)['customAttr'] = someVal |
第一种方法是新的