Cố gắng hiểu oop trong python Tôi đi vào tình huống này khiến tôi khó hiểu, và tôi không thể tìm được lời giải thích thỏa đáng ... Tôi đã xây dựng một lớp có thể đếm được, có bộ đếm thuộc tính đếm số lượng phiên bản của lớp đã được khởi tạo. Tôi muốn truy cập này được tăng lên khi một lớp con (hoặc lớp con) của lớp đã cho được khởi tạo. Đây là triển khai của tôi:Thừa kế các biến lớp trong python
class Countable(object):
counter = 0
def __new__(cls, *args, **kwargs):
cls.increment_counter()
count(cls)
return object.__new__(cls, *args, **kwargs)
@classmethod
def increment_counter(cls):
cls.counter += 1
if cls.__base__ is not object:
cls.__base__.increment_counter()
nơi count(cls)
có mục đích gỡ lỗi và sau đó ghi lại.
Bây giờ, chúng ta hãy có một số lớp con điều này:
class A(Countable):
def __init__(self, a='a'):
self.a = a
class B(Countable):
def __init__(self, b='b'):
self.b = b
class B2(B):
def __init__(self, b2='b2'):
self.b2 = b2
def count(cls):
print('@{:<5} Countables: {} As: {} Bs: {} B2s: {}'
''.format(cls.__name__, Countable.counter, A.counter, B.counter, B2.counter))
khi tôi chạy một mã như sau:
a = A()
a = A()
a = A()
b = B()
b = B()
a = A()
b2 = B2()
b2 = B2()
tôi có được đầu ra sau, trông xa lạ với tôi:
@A Countables: 1 As: 1 Bs: 1 B2s: 1
@A Countables: 2 As: 2 Bs: 2 B2s: 2
@A Countables: 3 As: 3 Bs: 3 B2s: 3
@B Countables: 4 As: 3 Bs: 4 B2s: 4
@B Countables: 5 As: 3 Bs: 5 B2s: 5
@A Countables: 6 As: 4 Bs: 5 B2s: 5
@B2 Countables: 7 As: 4 Bs: 6 B2s: 6
@B2 Countables: 8 As: 4 Bs: 7 B2s: 7
Tại sao khi bắt đầu cả bộ đếm A và B đều tăng, mặc dù tôi chỉ gọi số A()
? Và tại sao sau lần đầu tiên tôi gọi B()
nó hoạt động như mong đợi?
Tôi đã phát hiện ra rằng có một hành vi như tôi muốn nó là đủ để thêm counter = 0
tại mỗi phân lớp, nhưng tôi không thể tìm thấy giải thích tại sao nó hoạt động như thế .... Cảm ơn bạn!
Tôi đã thêm vài bản in gỡ lỗi và để đơn giản hóa việc tạo lớp giới hạn thành hai. Điều này khá lạ:
>>> a = A()
<class '__main__.A'> incrementing
increment parent of <class '__main__.A'> as well
<class '__main__.Countable'> incrementing
@A Counters: 1 As: 1 Bs: 1 B2s: 1
>>> B.counter
1
>>> B.counter is A.counter
True
>>> b = B()
<class '__main__.B'> incrementing
increment parent of <class '__main__.B'> as well
<class '__main__.Countable'> incrementing
@B Counters: 2 As: 1 Bs: 2 B2s: 2
>>> B.counter is A.counter
False
Làm thế nào khi B() chưa được khởi tạo, nó trỏ đến cùng biến với A.counter nhưng sau khi tạo một đối tượng thì nó khác?
Tôi không thể sao chép đầu ra của bạn. Đầu ra của tôi cho 'B2s' luôn giống như' Bs'. –
Tôi đã chỉnh sửa câu hỏi của bạn với ví dụ đơn giản về vấn đề. Đây là một câu hỏi thú vị, hy vọng ai đó có thể làm sáng tỏ một chút về quy trình – Vinny
@Rawing bạn là đúng, tôi dán kết quả của một ví dụ khác ... bây giờ tôi sửa nó! –