Python 中完整对象和子对象的计数
Count of full objects and subobjects in Python
我想维护 A 和 B 对象的计数,B 是 A 的子类。因此计数应该特定于 A 和 B。例如,如果我创建 3 个 A 对象和 2 个 B 对象,凭借在构造函数调用中,A 的计数变为 3+2=5,但我想保留为 3(当用作 B 的子对象时不是)。请评论以下代码片段:
class A:
acount = 0 # class variable
def __init__(self, isFullA = True):
if (isFullA):
self.iamFullA = True
A.acount += 1
else:
self.iamFullA = False
def __del__(self):
if (self.iamFullA):
A.acount -= 1
class B(A):
bcount = 0 # class variable
def __init__(self, isFullB = True):
A.__init__(self,False)
if (isFullB):
self.iamFullB = True
B.bcount += 1
else:
self.iamFullB = False
def __del__(self):
if (self.iamFullB):
B.bcount -= 1
#MAIN
L=[]
for i in range(3):
L.append(A())
for i in range(2):
L.append(B())
print "A.acount = " + str(A.acount)
print "B.bcount = " + str(B.bcount)
输出为:
A.acount = 3
B.bcount = 2
你让它变得复杂 - 你所需要的只是为每个 class:
有一个独特的 count
class 属性
class A(object):
_counter = 0
@classmethod
def _inc(cls):
cls._counter += 1
@classmethod
def _dec(cls):
cls._counter -= 1
@classmethod
def get_count(cls):
return cls._counter
def __init__(self):
self._inc()
def __del__(self):
self._dec()
class B(A):
_counter = 0
def __init__(self, wot):
super(B, self).__init__()
self.wot = wot
L=[]
for i in range(3):
L.append(A())
for i in range(2):
L.append(B(i))
print "A.count = {}".format(A.get_count())
print "B.count = {}".format(B.get_count())
请注意,我使用 classmethods
来确保我们正在访问 class 属性,因为 __init__
中的 self._counter += 1
会创建一个实例属性。您也可以使用 type(self)._counter += 1
(或 self.__class__._counter += 1
)获得正确的行为,但这有点难看。
如果这是 API 其他开发者将以此为基础的,您可能需要使用自定义元 class 来确保每个子 class 都有自己的 _counter
,即:
class CounterType(type):
def __new__(meta, name, bases, attribs):
if "_counter" not in attribs:
attribs["_counter"] = 0
return type.__new__(meta, name, bases, attribs)
class CounterBase(object):
__metaclass__ = CounterType
@classmethod
def _inc(cls):
cls._counter += 1
@classmethod
def _dec(cls):
cls._counter -= 1
@classmethod
def get_count(cls):
return cls._counter
def __init__(self):
self._inc()
def __del__(self):
self._dec()
class A(CounterBase):
pass
class B(A):
def __init__(self, wot):
super(B, self).__init__()
self.wot = wot
L=[]
for i in range(3):
L.append(A())
for i in range(2):
L.append(B(i))
print "A.count = {}".format(A.get_count())
print "B.count = {}".format(B.get_count())
我想维护 A 和 B 对象的计数,B 是 A 的子类。因此计数应该特定于 A 和 B。例如,如果我创建 3 个 A 对象和 2 个 B 对象,凭借在构造函数调用中,A 的计数变为 3+2=5,但我想保留为 3(当用作 B 的子对象时不是)。请评论以下代码片段:
class A:
acount = 0 # class variable
def __init__(self, isFullA = True):
if (isFullA):
self.iamFullA = True
A.acount += 1
else:
self.iamFullA = False
def __del__(self):
if (self.iamFullA):
A.acount -= 1
class B(A):
bcount = 0 # class variable
def __init__(self, isFullB = True):
A.__init__(self,False)
if (isFullB):
self.iamFullB = True
B.bcount += 1
else:
self.iamFullB = False
def __del__(self):
if (self.iamFullB):
B.bcount -= 1
#MAIN
L=[]
for i in range(3):
L.append(A())
for i in range(2):
L.append(B())
print "A.acount = " + str(A.acount)
print "B.bcount = " + str(B.bcount)
输出为:
A.acount = 3
B.bcount = 2
你让它变得复杂 - 你所需要的只是为每个 class:
有一个独特的count
class 属性
class A(object):
_counter = 0
@classmethod
def _inc(cls):
cls._counter += 1
@classmethod
def _dec(cls):
cls._counter -= 1
@classmethod
def get_count(cls):
return cls._counter
def __init__(self):
self._inc()
def __del__(self):
self._dec()
class B(A):
_counter = 0
def __init__(self, wot):
super(B, self).__init__()
self.wot = wot
L=[]
for i in range(3):
L.append(A())
for i in range(2):
L.append(B(i))
print "A.count = {}".format(A.get_count())
print "B.count = {}".format(B.get_count())
请注意,我使用 classmethods
来确保我们正在访问 class 属性,因为 __init__
中的 self._counter += 1
会创建一个实例属性。您也可以使用 type(self)._counter += 1
(或 self.__class__._counter += 1
)获得正确的行为,但这有点难看。
如果这是 API 其他开发者将以此为基础的,您可能需要使用自定义元 class 来确保每个子 class 都有自己的 _counter
,即:
class CounterType(type):
def __new__(meta, name, bases, attribs):
if "_counter" not in attribs:
attribs["_counter"] = 0
return type.__new__(meta, name, bases, attribs)
class CounterBase(object):
__metaclass__ = CounterType
@classmethod
def _inc(cls):
cls._counter += 1
@classmethod
def _dec(cls):
cls._counter -= 1
@classmethod
def get_count(cls):
return cls._counter
def __init__(self):
self._inc()
def __del__(self):
self._dec()
class A(CounterBase):
pass
class B(A):
def __init__(self, wot):
super(B, self).__init__()
self.wot = wot
L=[]
for i in range(3):
L.append(A())
for i in range(2):
L.append(B(i))
print "A.count = {}".format(A.get_count())
print "B.count = {}".format(B.get_count())