Trong Python 3 mã của bạn sẽ hoạt động, nhưng trong Python 2 có một số gói diễn ra khi phương pháp được tìm kiếm.
Lớp vs Instance
mức lớp: lưu trữ counter
với chức năng (hoặc trực tiếp, hoặc bằng cách sử dụng một mặc định có thể thay đổi) có hiệu quả làm cho nó một thuộc tính mức lớp như chỉ có bao giờ một trong những chức năng, không có vấn đề bao nhiêu trường hợp bạn có (tất cả họ chia sẻ cùng một đối tượng chức năng).
mức dụ: để làm cho counter
mức dụ thuộc tính bạn cần phải tạo ra các chức năng trong __init__
, sau đó quấn nó với functools.partial
(vì vậy nó hoạt động như một phương pháp thông thường), và sau đó lưu trữ nó trên dụ - bây giờ bạn có một đối tượng hàm cho mỗi cá thể.
Lớp Cấp
Việc thực hành chấp nhận cho một biến tĩnh giống như là sử dụng một đối số mặc định có thể thay đổi:
class foo(object):
...
def bar(self, _counter=[0]):
_counter[0] += 1
return _counter[0]
Nếu bạn muốn nó được đẹp hơn bạn có thể định nghĩa của riêng bạn có thể thay đổi vùng chứa:
class MutableDefault(object):
def __init__(self, start=0):
self.value = start
def __iadd__(self, other):
self.value += other
return self
def value(self):
return self.value
và thay đổi mã của bạn như vậy:
class foo(object):
def bar(self, _counter=MutableDefault()):
_counter += 1
return _counter.value
mức Instance
from functools import partial
class foo(object):
def __init__(self):
def bar(self, _counter=MutableDefault(1)): # create new 'bar' each time
value = _counter.value
_counter += 1
return value
self.bar = partial(bar, self)
Tóm tắt
Như bạn thấy, dễ đọc mất một hit nghiêm trọng khi di chuyển đến cấp độ dụ cho counter
. Tôi đề nghị bạn đánh giá lại tầm quan trọng của việc nhấn mạnh rằng counter
là một phần của bar
và nếu điều đó thực sự quan trọng có thể làm cho lớp học của riêng mình trở thành một phần của các trường hợp foo
. Nếu nó không thực sự quan trọng, hãy làm theo cách thông thường:
class foo(object):
def __init__(self):
self.bar_counter = 0
def bar(self):
self.bar_counter += 1
return self.bar_counter
Nguồn
2012-03-01 20:52:56
nên 'counter' được cấp lớp (tất cả các trường chia sẻ số lượng hiện tại), hoặc mức dụ (mỗi trường hợp sẽ bắt đầu từ 1)? –
'truy cập' phải là trường hợp cấp – sbell
Câu hỏi liên quan này có thể (hoặc có thể không) hữu ích: http://stackoverflow.com/questions/7034063/adding-attributes-the-instancemethods-in-python –