问题
Using python, one can set an attribute of a instance via either of the two methods below:
>>> class Foo(object):
pass
>>> a = Foo()
>>> a.x = 1
>>> a.x
1
>>> setattr(a, 'b', 2)
>>> a.b
2
One can also assign properties via the property decorator.
>>> class Bar(object):
@property
def x(self):
return 0
>>> a = Bar()
>>> a.x
0
My question is, how can I assign a property to an instance?
My intuition was to try something like this...
>>> class Doo(object):
pass
>>> a = Doo()
>>> def k():
return 0
>>> a.m = property(k)
>>> a.m
<property object at 0x0380F540>
... but, I get this weird property object. Similar experimentation yielded similar results. My guess is that properties are more closely related to classes than instances in some respect, but I don't know the inner workings well enough to understand what's going on here.
回答1:
It is possible to dynamically add properties to a class after it's already created:
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
However, you can't set a property on an instance, only on a class. You can use an instance to do it:
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
See How to add property to a class dynamically? for more information.
回答2:
Properties use descriptors which only work on classes and thus for all instances. But you could use a combination of a descriptor on a class that would consult a per-instance function.
>>> 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
回答3:
You can assign the property directly to the class object:
>>> 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
回答4:
Here we have taken @agf's solution and used a lambda
function to define the class property.
class A(object):
pass
a = A()
a.__class__.f = property(lambda self: 57)
a.f # 57
The following post provides more context: https://crosscompute.com/n/jAbsB6OIm6oCCJX9PBIbY5FECFKCClyV/_/Assign%20a%20class%20property%20to%20an%20instance
来源:https://stackoverflow.com/questions/7117892/how-do-i-assign-a-property-to-an-instance-in-python