Py学习  »  Python

python在创建新对象时设置属性__

aaa90210 • 4 年前 • 650 次点击  

当使用“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”返回的实例,它允许在成为完整类实例之前设置属性?我对解决方案不感兴趣,比如在创建实例后设置类。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/44169
 
650 次点击  
文章 [ 1 ]  |  最新文章 4 年前
ShadowRanger
Reply   •   1 楼
ShadowRanger    5 年前

你必须明确地绕过你自己的班级 __setattr__ 打电话给 super 或根 object 第二组 . 所以你会改变:

obj.customAttr = someVal

到:

object.__setattr__(obj, 'customAttr', someVal)

不太普遍的方法(不适用于 __slots__ 是直接分配给 __dict__ 使用 dict 操作:

obj.__dict__['customAttr'] = someVal  # Equivalently: vars(obj)['customAttr'] = someVal

第一种方法是 the newly __slots__ -ed uuid.UUID 现在使用; before it became __slots__ -ed, it used the second approach . 在这两种情况下都需要这样做,因为他们使用相同的 第二组 使类型尽可能不可变的诀窍(不必麻烦地进行子类化 tuple , a la typing.NamedTuple )。