2009-10-06 41 views
6

Tôi sử dụng 'thuộc tính' để đảm bảo rằng các thay đổi đối với một biến đối tượng được bao bọc bởi các phương thức mà tôi cần.Biến đối tượng không đổi?

Điều gì xảy ra khi một cá thể có biến không hợp lý nên thay đổi? Ví dụ, nếu tôi đang tạo một lớp cho một Process, mỗi cá thể Process sẽ có một thuộc tính pid mà thường xuyên được truy cập nhưng không nên thay đổi.

Cách Pythonic nhất để xử lý ai đó đang cố gắng sửa đổi biến thể hiện đó là gì?

  • Chỉ cần tin tưởng người dùng không thử và thay đổi điều gì đó mà họ không nên làm?

  • Sử dụng thuộc tính nhưng tăng ngoại lệ nếu biến mẫu là đã thay đổi?

  • Cái gì khác?

+0

http://stackoverflow.com/questions/1358711/raising-an-exception-on-updating-a-constant-attribute-in-python –

Trả lời

6

tên Thêm vào trước của biến với __, và tạo thuộc tính chỉ đọc, Python sẽ chăm sóc ngoại lệ, và biến mình sẽ được bảo vệ khỏi tình cờ ghi đè.

class foo(object): 
    def __init__(self, bar): 
     self.__bar = bar 

    @property 
    def bar(self): 
     return self.__bar 

f = foo('bar') 
f.bar   # => bar 
f.bar = 'baz' # AttributeError; would have to use f._foo__bar 
+0

Trong hai dòng cuối cùng, bạn có nghĩa là "f.foo" và "f .foo = 'baz' ", phải không? –

+0

Vâng, tôi đã trộn lẫn tên biến. Đã sửa chữa. –

+1

Tôi thấy các thuộc tính "riêng tư" bị xáo trộn sẽ gây rắc rối nhiều hơn chúng đáng giá. Một dấu gạch dưới đơn sẽ làm cho phân lớp dễ dàng hơn trong khi vẫn giao tiếp "không chạm vào" này cho người dùng. –

1

Có thể bạn có thể ghi đè __setattr__? Trong dòng,

def __setattr__(self, name, value): 
    if self.__dict__.has_key(name): 
     raise TypeError, 'value is read only' 
    self.__dict__[name] = value 
3

Đơn giản là tin tưởng người dùng không nhất thiết phải là điều xấu; nếu bạn chỉ đang viết một chương trình Python nhanh chóng được sử dụng một lần và bị vứt đi, bạn có thể rất tin tưởng rằng người dùng không thay đổi trường pid.

IMHO cách Pythonic nhất để thực thi trường chỉ đọc là sử dụng thuộc tính làm tăng ngoại lệ khi cố gắng đặt trường.

Vì vậy, IMHO bạn có bản năng tốt về nội dung này.

1

Chỉ cần sử dụng thuộc tính và thuộc tính ẩn (bắt đầu bằng một số gạch dưới).

Thuộc tính đơn giản là chỉ đọc!

>>> class Test (object): 
... @property 
... def bar(self): 
... return self._bar 
... 
>>> t = Test() 
>>> t._bar = 2 
>>> t.bar 
2 
>>> t.bar = 2 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: can't set attribute 

Ẩn với dấu gạch dưới kép không được sử dụng để ẩn cài đặt, nhưng để đảm bảo bạn không va chạm với thuộc tính của lớp con; xem xét một mixin ví dụ, nó phải rất cẩn thận!

Nếu bạn chỉ muốn ẩn thuộc tính, hãy sử dụng một dấu gạch dưới. Và như bạn thấy không có thêm ma thuật để thêm vào - nếu bạn không định nghĩa một hàm được đặt, thuộc tính của bạn chỉ là giá trị chỉ đọc là giá trị trả về của một phương thức.

Các vấn đề liên quan