试图理解python中的oop我进入这种困惑我的情况,我无法找到令人满意的解释... 我正在构建一个Countable类,它有一个计数器属性,用于统计该类的多少个实例已被初始化。我想要在给定类的子类(或子类)初始化时增加此计数器。下面是我的实现: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()
其中count(cls)
是有调试的目的,后来我把它写下来。
现在,让我们有这样一些子类:
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))
当我运行类似下面的代码:
a = A()
a = A()
a = A()
b = B()
b = B()
a = A()
b2 = B2()
b2 = B2()
我得到下面的输出,这看起来很奇怪对我说:
@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
为什么在开始时A和B的计数器都在递增,尽管我只打电话给A()
?为什么在我第一次打电话B()
后,它的行为如预期般?
我已经发现有一个像我想要的行为就足够在每个子类中添加counter = 0
,但我无法找到解释为什么它的行为如此....谢谢!
我添加了几个调试打印,并且为了简单起见,限制类创建为两个。这是很奇怪:
>>> 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
为什么当B()尚未初始化,它指向相同的变量A.counter但创建一个对象后,这是一个不同?
我无法重现你的输出。我的'B2s'输出总是和'Bs'一样。 –
我用这个问题的简单例子编辑了你的问题。这是一个有趣的问题,希望有人能对这个过程有所了解 – Vinny
@Rawing你是对的,我粘贴另一个例子的输出......现在我修复它! –