2011-08-19 31 views
5

Sử dụng python, người ta có thể thiết lập một thuộc tính của một cá thể thông qua một trong hai phương thức dưới đây:Làm cách nào để gán một thuộc tính cho một thể hiện bằng Python?

>>> class Foo(object): 
    pass 

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

Một cũng có thể gán thuộc tính thông qua trang trí bất động sản.

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


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

Câu hỏi của tôi là, làm cách nào để chỉ định thuộc tính cho một cá thể?

trực giác của tôi là cố gắng một cái gì đó như thế này ...

>>> class Doo(object): 
    pass 

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

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

... nhưng, tôi nhận được đối tượng sở hữu kỳ lạ này. Thử nghiệm tương tự cũng mang lại kết quả tương tự. Tôi đoán là các thuộc tính có liên quan chặt chẽ hơn đến các lớp so với các trường hợp trong một số khía cạnh, nhưng tôi không biết các hoạt động bên trong cũng đủ để hiểu những gì đang xảy ra ở đây.

Trả lời

4

Có thể tự động thêm các thuộc tính vào một lớp học sau khi nó đã được tạo ra:

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 

Tuy nhiên, bạn không thể thiết lập một tài sản trên một thể hiện, chỉ trên một lớp. Bạn có thể sử dụng một phiên bản để làm điều đó:

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 

Xem How to add property to a class dynamically? để biết thêm thông tin.

+1

Tôi khá chắc chắn rằng họ cần điều này là mỗi ví dụ. Những gì bạn đề xuất sẽ ảnh hưởng đến tất cả các trường hợp. –

+0

Argh! 1 phút trước tôi !! :) +1 – rubik

+2

@Ross - Tôi biết, nó nói rằng trong câu trả lời. Nó chỉ đơn giản là không thể thêm một thuộc tính vào một thể hiện. Xem chuỗi tôi đã liên kết. – agf

1

Bạn có thể gán tài sản trực tiếp đến đối tượng lớp:

>>> 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

Thuộc tính sử dụng descriptors mà chỉ làm việc trên lớp và do đó cho tất cả các trường. Nhưng bạn có thể sử dụng kết hợp mô tả trên một lớp sẽ tham khảo chức năng cho từng trường hợp.

>>> 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 
Các vấn đề liên quan