8

在下面的 B 类中,我希望__set__每当您将值分配给时调用 A 类中的函数B().a。相反,将值设置为用该值B().a覆盖B().a。分配给的 C 类C().a可以正常工作,但我想为每个用户类创建一个单独的 A 实例,即我不想在 C() 的一个实例中更改“a”来更改所有其他实例中的“a”。我写了几个测试来帮助说明这个问题。你能帮我定义一个同时通过 test1 和 test2 的类吗?

class A(object):
    def __set__(self, instance, value):
        print "__set__ called: ", value

class B(object):
    def __init__(self):
        self.a = A()

class C(object):
    a = A()

def test1( class_in ):
    o = class_in()
    o.a = "test"
    if isinstance(o.a, A):
        print "pass"
    else:
        print "fail"

def test2( class_in ):
    o1, o2 = class_in(), class_in()
    if o1.a is o2.a:
        print "fail"
    else:
        print "pass"
4

3 回答 3

5

根据文档

以下方法仅适用于包含该方法的类(所谓的描述符类)的实例出现在另一个新样式类(称为所有者类)的类字典中时。在下面的示例中,“属性”是指名称为所有者类中属性键的属性__dict__。描述符本身只能实现为新型类。

所以你不能在实例上有描述符。

但是,由于描述符获取了用于访问它的实例的引用,因此只需将其用作存储状态的键,并且您可以根据实例具有不同的行为。

于 2009-06-16T22:29:29.983 回答
0

这是一个可以通过原始测试的类,但在大多数情况下不要尝试使用它。它无法通过自身的 isinstance 测试!

class E(object):
    def __new__(cls, state):
        class E(object):
            a = A(state)
            def __init__(self, state):
                self.state = state
        return E(state)

#>>> isinstance(E(1), E)
#False
于 2009-06-17T00:12:40.103 回答
0

我被一个类似的问题所困扰,因为我想对具有由描述符控制的属性的对象进行分类。当我这样做时,我注意到所有对象中的属性都被覆盖了,因此它们不是单独的。

我提出了一个 SO 问题,得到的答案就在这里:class attribute changed value for no reason

一个讨论描述符的好文档链接在这里: http: //martyalchin.com/2007/nov/24/python-descriptors-part-2-of-2/

来自上述链接的示例描述符如下:

class Numberise(object):
    def __init__(self, name):
        self.name = name

    def __get__(self, instance, owner):
        if self.name not in instance.__dict__:
            raise (AttributeError, self.name)
        return '%o'%(instance.__dict__[self.name])

    def __set__(self, instance, value):
        print ('setting value to: %d'%value)
        instance.__dict__[self.name] = value
于 2014-03-08T02:53:21.117 回答