Tôi có một lớp chung mà người dùng nên phân lớp để triển khai các phương thức nhất định. Có thể có một số danh mục con sâu sắc. hơi giống
lớp Điều (đối tượng):
def fun(self, *args, **kwargs):
raiseNotImplementedError()
chuông lớp(Điều):
def vui vẻ (tự):
return 1
Còi lớp (Chuông):
def vui vẻ (tự):
return super(Còi, self).fun() + 1
Tôi muốn tính toán khi sử dụng Điều
bất kỳ lớp con nào của vui vẻ()
Số lần nó được gọi. Bởi vì các trang trí không được kế thừa và vì tôi không muốn người dùng phải nhớ trang trí vui vẻ()
phương pháp, vì vậy sự hiểu biết của tôi là siêu dữ liệu là con đường để đi. vì vậy tôi đã viết
lớp CountCalls(loại):
def __new__(cls, name, base, attrs):
attrs["_origin_fun"] = attrs["fun"]
attrs["fun"] = countcalls(attrs["_origin_fun"])
return super(CountCalls, cls).__new__(cls, name, base, attrs)
其中 đếm số cuộc gọi
Là một công cụ trang trí cổ điển đếm số lượng cuộc gọi:
số lượng cuộc gọi def(fn):
trình bao bọc def(*args, **kwargs):
bao bọc.ncalls += 1
return fn(*args, **kwargs)
bao bọc.ncalls = 0
bao bọc.__name__ = fn.__name__
bao bọc.__doc__ = fn.__doc__
giấy gói trả lại
và sẽ Điều
Định nghĩa của được thay đổi thành
lớp Điều (đối tượng):
__metaclass__ = Đếm số cuộc gọi
def fun(self, *args, **kwargs):
raiseNotImplementedError()
câu hỏi:Cách này có tác dụng nhưng có tác dụng phụ ngoài ý muốn, cụ thể là khi vui vẻ()
gọi bất kìCác phương pháp ví dụ:
>>> b1 = Chuông()
>>> b2 = Chuông()
>>> b1.fun.ncalls, b2.fun.ncalls
(0, 0)
>>> b1.fun()
1
>>> b1.fun.ncalls, b2.fun.ncalls
(1, 1)
câu hỏi:Cách tính từng cặp mẫu vui vẻ()
số lượng cuộc gọi? Có vẻ như tôi nên triển khai nó trong siêu dữ liệu __init__
thay vì __mới__
, nhưng đến giờ tôi vẫn chưa tìm được cú pháp đúng. Ví dụ, sử dụng
def __init__(bản thân, tên, căn cứ, attr):
attrs["_origin_fun"] = attrs["fun"]
attrs["fun"] = countcalls(attrs["_origin_fun"])
super(CountCalls, self).__init__(tên, căn cứ, attrs)
Năng suất
>>> b = Chuông()
>>> b.fun.ncalls
Traceback (most recent call last):
File "", line 1, in
AttributionError: đối tượng 'function' không có thuộc tính 'ncalls'
Cảm ơn!
Bạn có thể bỏ qua siêu dữ liệu bằng cách thay đổi mẫu kế thừa một chút:
lớp Điều (đối tượng):
def __init__(self):
self.fun_calls = 0
def fun(self, *args, **kwargs):
self.fun_calls += 1
self._fun(*args, **kwargs)
def _fun(self, *args, **kwargs):
raiseNotImplementedError()
Sau đó chỉ cần ghi đè vào lớp con của bạn _vui vẻ
Thế thôi. Điều này cho phép bạn tự động đếm theo phiên bản, đồng thời (imo) sạch hơn và dễ hiểu hơn so với việc triển khai siêu dữ liệu.
Tôi là một lập trình viên xuất sắc, rất giỏi!