【问题标题】:Count of full objects and subobjects in PythonPython中完整对象和子对象的计数
【发布时间】:2015-12-18 09:34:35
【问题描述】:

我想维护 A 和 B 对象的计数,B 是 A 的子类。所以计数应该特定于 A 和 B。例如,如果我通过构造函数创建 3 个 A 对象和 2 个 B 对象调用,A 的计数变为 3+2=5,但我想保留为 3(而不是用作 B 的子对象时)。请评论以下代码sn-p:

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

【问题讨论】:

  • 那么,您的问题是什么?如果您只想进行代码审查,请转到codereview.stackexchange.com
  • if isinstance(self, A): A.acount += 1 呢?

标签: python class class-variables subobject


【解决方案1】:

你让它变得复杂了——你只需要为每个类都有一个独特的 count 类属性:

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 来确保我们正在访问类属性,因为__init__ 中的self._counter += 1 将创建一个实例属性。您也可以使用type(self)._counter += 1(或self.__class__._counter += 1)获得正确的行为,但这有点难看。

如果这是其他开发人员将基于的 API,您可能需要使用自定义元类来确保每个子类都有自己的 _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())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 2015-04-11
    • 2014-05-17
    相关资源
    最近更新 更多