2015-12-18 4 views
0

Je souhaite gérer le nombre d'objets A et B, B est sous-classé à partir de A. Les comptages doivent donc être spécifiques à A et B. Par exemple, si je crée 3 objets A et 2 objets B, en vertu de l'appel du constructeur, compte pour A devient 3 + 2 = 5, mais je voudrais garder comme 3 (pas lorsqu'il est utilisé comme un sous-objet dans le cadre de B). S'il vous plaît commenter l'extrait de code suivant:Nombre d'objets complets et de sous-objets en Python

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) 

La sortie est:

A.acount = 3 
B.bcount = 2 
+1

Alors, quelle est votre question? Si vous souhaitez uniquement consulter le code, rendez-vous sur http://codereview.stackexchange.com/. – Holt

+0

qu'en est-il de 'if isinstance (self, A): A.acount + = 1'? – Pynchia

Répondre

0

Vous faites ce moyen de compliqué - tout ce que vous avez besoin est d'avoir un attribut de classe count distincte pour chaque classe:

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()) 

Notez que je classmethods pour nous assurer accédons l'attribut de classe, comme dans le self._counter += 1__init__ serait créer un attribut d'instance. Vous pouvez également obtenir le bon comportement en utilisant type(self)._counter += 1 (ou self.__class__._counter += 1) mais c'est un peu moche imho.

Si cela est une API d'autres développeurs se fonderont sur, vous pouvez utiliser un métaclasse personnalisé pour garantir que chaque sous-classe a sa propre _counter, à savoir:

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())