In class B below I wanted the __set__
function in class A to be called whenever you assign a value to B().a
. Instead, setting a value to B().a
overwrites B().a
with the value. Class C assigning to C().a
works correctly, but I wanted to have a separate instance of A for each user class, i.e. I don't want changing 'a' in one instance of C() to change 'a' in all other instances. I wrote a couple of tests to help illustrate the problem. Can you help me define a class that will pass both test1 and test2?
在下面的B类中,每当你为B()赋值时,我都希望调用A类中的__set__函数。而是将值设置为B()。a用值覆盖B()。a。分配给C()。a的C类工作正常,但我想为每个用户类分别设置一个A实例,即我不想在C()的一个实例中更改'a'来改变'a'in所有其他情况。我写了几个测试来帮助说明问题。你能帮我定一个会传递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"
3 个解决方案
#1
Accordingly to the documentation:
根据文件:
The following methods only apply when an instance of the class containing the method (a so-called descriptor class) appears in the class dictionary of another new-style class, known as the owner class. In the examples below, “the attribute” refers to the attribute whose name is the key of the property in the owner class’
__dict__
. Descriptors can only be implemented as new-style classes themselves.以下方法仅适用于包含该方法的类的实例(所谓的描述符类)出现在另一个新样式类的类字典中,称为所有者类。在下面的示例中,“属性”是指属性,其名称是所有者类'__dict__中属性的键。描述符只能作为新式类本身实现。
So you can't have descriptors on instances.
所以你不能在实例上有描述符。
However, since the descriptor gets a ref to the instance being used to access it, just use that as a key to storing state and you can have different behavior depending on the instance.
但是,由于描述符获取了用于访问它的实例的ref,因此只需将其用作存储状态的键,您可以根据实例使用不同的行为。
#2
Here's a class that can pass the original tests, but don't try using it in most situations. it fails the isinstance test on itself!
这是一个可以通过原始测试的类,但在大多数情况下不要尝试使用它。它没有通过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
#3
I was bitten by a similar issue in that I wanted to class objects with attributes governed by a descriptor. When I did this, I noticed that the attributes were being overwritten in all of the objects such that they weren't individual.
我被一个类似的问题所困扰,因为我想用具有描述符的属性对象进行分类。当我这样做时,我注意到所有对象中的属性都被覆盖,因此它们不是个体。
I raised a SO question and the resultant answer is here: class attribute changing value for no reason
我提出了一个SO问题,结果答案就在这里:类属性无缘无故改变值
A good document link discussing descriptors is here: http://martyalchin.com/2007/nov/24/python-descriptors-part-2-of-2/
讨论描述符的好文档链接在这里:http://martyalchin.com/2007/nov/24/python-descriptors-part-2-of-2/
An example descriptor from the aforementioned link is below:
上述链接的示例描述符如下:
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
#1
Accordingly to the documentation:
根据文件:
The following methods only apply when an instance of the class containing the method (a so-called descriptor class) appears in the class dictionary of another new-style class, known as the owner class. In the examples below, “the attribute” refers to the attribute whose name is the key of the property in the owner class’
__dict__
. Descriptors can only be implemented as new-style classes themselves.以下方法仅适用于包含该方法的类的实例(所谓的描述符类)出现在另一个新样式类的类字典中,称为所有者类。在下面的示例中,“属性”是指属性,其名称是所有者类'__dict__中属性的键。描述符只能作为新式类本身实现。
So you can't have descriptors on instances.
所以你不能在实例上有描述符。
However, since the descriptor gets a ref to the instance being used to access it, just use that as a key to storing state and you can have different behavior depending on the instance.
但是,由于描述符获取了用于访问它的实例的ref,因此只需将其用作存储状态的键,您可以根据实例使用不同的行为。
#2
Here's a class that can pass the original tests, but don't try using it in most situations. it fails the isinstance test on itself!
这是一个可以通过原始测试的类,但在大多数情况下不要尝试使用它。它没有通过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
#3
I was bitten by a similar issue in that I wanted to class objects with attributes governed by a descriptor. When I did this, I noticed that the attributes were being overwritten in all of the objects such that they weren't individual.
我被一个类似的问题所困扰,因为我想用具有描述符的属性对象进行分类。当我这样做时,我注意到所有对象中的属性都被覆盖,因此它们不是个体。
I raised a SO question and the resultant answer is here: class attribute changing value for no reason
我提出了一个SO问题,结果答案就在这里:类属性无缘无故改变值
A good document link discussing descriptors is here: http://martyalchin.com/2007/nov/24/python-descriptors-part-2-of-2/
讨论描述符的好文档链接在这里:http://martyalchin.com/2007/nov/24/python-descriptors-part-2-of-2/
An example descriptor from the aforementioned link is below:
上述链接的示例描述符如下:
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