Đôi khi văn bản phải được đọc nhiều hơn để tìm ra hương vị của ý tưởng hơn là để biết chi tiết. Đây là một trong những trường hợp đó.
Trong trang được liên kết , các Ví dụ 2.5, 2.6 và 2.7 đều phải sử dụng một phương pháp , do_your_stuff
. (Đó là, do_something
nên được đổi thành do_your_stuff
.)
Ngoài ra, như Ned Deily đã chỉ ra , A.do_your_stuff
phải là một phương thức lớp.
class A(object):
@classmethod
def do_your_stuff(cls):
print 'This is A'
class B(A):
@classmethod
def do_your_stuff(cls):
super(B, cls).do_your_stuff()
B.do_your_stuff()
super(B, cls).do_your_stuff
trả về một phương thức liên kết (xem chú thích 2 ). Vì cls
đã được truyền làm đối số thứ hai super()
, nó cls
được liên kết với phương thức được trả về. Nói cách khác, cls
được chuyển làm đối số đầu tiên cho phương thức do_your_stuff()
của lớp A.
Để nhắc lại: phương thức của super(B, cls).do_your_stuff()
nguyên nhân được gọi với truyền là đối số đầu tiên. Để điều đó hoạt động, 's
phải là một phương thức lớp. Trang được liên kết không đề cập đến điều đó, nhưng đó chắc chắn là trường hợp.A
do_your_stuff
cls
A
do_your_stuff
Tái bút. do_something = classmethod(do_something)
là cách cũ để thực hiện một phương pháp phân loại. Cách mới (er) là sử dụng trình trang trí @classmethod.
Lưu ý rằng super(B, cls)
không thể thay thế bằng super(cls, cls)
. Làm như vậy có thể dẫn đến vòng lặp vô hạn. Ví dụ,
class A(object):
@classmethod
def do_your_stuff(cls):
print('This is A')
class B(A):
@classmethod
def do_your_stuff(cls):
print('This is B')
super(cls, cls).do_your_stuff()
class C(B):
@classmethod
def do_your_stuff(cls):
print('This is C')
super(cls, cls).do_your_stuff()
C.do_your_stuff()
sẽ nâng cao RuntimeError: maximum recursion depth exceeded while calling a Python object
.
Nếu cls
có C
, hãy super(cls, cls)
tìm kiếm C.mro()
lớp đứng sau C
.
In [161]: C.mro()
Out[161]: [__main__.C, __main__.B, __main__.A, object]
Kể từ khi lớp học đó là B
, khi cls
là C
, super(cls, cls).do_your_stuff()
luôn luôn kêu gọi B.do_your_stuff
. Vì super(cls, cls).do_your_stuff()
được gọi bên trong B.do_your_stuff
, bạn sẽ gọi B.do_your_stuff
trong một vòng lặp vô hạn.
Trong Python3, dạng đối số 0 củasuper
đã được thêm vào để super(B, cls)
có thể được thay thế bằng super()
và Python3 sẽ tìm ra từ ngữ cảnh mà super()
trong định nghĩa của class B
phải tương đương với super(B, cls)
.
Nhưng không có trường hợp nào super(cls, cls)
(hoặc vì những lý do tương tự, super(type(self), self)
) luôn đúng.