2011-08-19 79 views
5

使用Python,一个可经由任一下面的两种方法中的设定的实例属性:如何将属性分配给Python中的实例?

>>> class Foo(object): 
    pass 

>>> a = Foo() 
>>> a.x = 1 
>>> a.x 
1 
>>> setattr(a, 'b', 2) 
>>> a.b 
2 

人们也可以通过属性装饰分配属性。

>>> class Bar(object): 
    @property 
    def x(self): 
     return 0 


>>> a = Bar() 
>>> a.x 
0 

我的问题是,我怎样才能将一个属性分配给一个实例?

我的直觉是要尝试这样的事情......

>>> class Doo(object): 
    pass 

>>> a = Doo() 
>>> def k(): 
    return 0 

>>> a.m = property(k) 
>>> a.m 
<property object at 0x0380F540> 

...但是,我得到这个奇怪的属性对象。类似的实验产生了类似的结果。我的猜测是,属性在某些方面与实例相比更密切相关,但我不知道内部工作是否足以理解这里发生的事情。

回答

4

有可能它已经创建后动态属性添加到一个类:

class Bar(object): 
    def x(self): 
     return 0 

setattr(Bar, 'x', property(Bar.x)) 

print Bar.x 
# <property object at 0x04D37270> 
print Bar().x 
# 0 

但是,你不能设置属性上的情况下,只有一类。你可以用一个实例来做到这一点:

class Bar(object): 
    def x(self): 
     return 0 

bar = Bar() 

setattr(bar.__class__, 'x', property(bar.__class__.x)) 

print Bar.x 
# <property object at 0x04D306F0> 
print bar.x 
# 0 

更多信息请参见How to add property to a class dynamically?

+1

我敢肯定,他们需要这是每个实例。你的建议会影响所有实例。 –

+0

啊! 1分钟前我! :) +1 – rubik

+2

@罗斯 - 我知道,它说,在答案。它根本不可能添加一个属性到一个实例。看到我链接的线程。 – agf

1

您可以直接财产分配给类对象:

>>> class Foo(object): 
    pass  
>>> a = Foo() 
>>> a.__class__ 
__main__.Foo  
>>> setattr(a.__class__, 'm', property(lambda self: 0)) 
>>> a.m 
0 
>>> a.m = 24 
AttributeError: can't set attribute 
2

属性使用descriptors只在类工作,从而 所有实例。但是,您可以使用 上的描述符组合来查询每个实例的函数。

>>> class Foo(object): 
...  @property 
...  def x(self): 
...   if 'x' in self.__dict__: 
...    return self.__dict__['x'](self) 
... 
>>> a = Foo() 
>>> def k(self): 
...  return 0 
... 
>>> a.__dict__['x'] = k 
>>> a.x 
0 
相关问题