2011-12-25 11 views
10

Byłem czyszczenie kodu z modułu Mam przedłużające i nie wydaje się znaleźć sposób, aby Pythonify ten kod:Zliczanie wystąpień klasy?

global_next_id = 1 

class Obj: 
    def __init__(self): 
    global global_next_id 
    self.id = global_next_id 

    global_next_id += 1 

Ten kod wykorzystuje globalny identyfikator śledzić przypadkach klasy (potrzebuję również wewnętrznie zmiennej i musi to być liczba).

Czy ktoś może zaproponować sposób na Pythonify tego kodu?

+1

Dlaczego trzeba „śledzić instancji klasy” z globalnym id? –

+1

Jest to dla biblioteki PDF, którą modyfikuję. Każdy plik PDF 'Obj' musi zostać wydrukowany z odpowiednim identyfikatorem. – Blender

Odpowiedz

34

spróbować czegoś takiego:

from itertools import count 

class Obj(object): 
    _ids = count(0) 

    def __init__(self): 
    self.id = next(self._ids) 
+1

Całkowicie przeoczyłem zmienne klasy ... Dzięki za rozwiązanie 'itertools'! – Blender

+1

Chciałbym móc ubiegać się o przyznanie mi jedynego kredytu - widziałem go gdzieś tutaj w innym poście. Jest elegancki i wydajny. –

+0

Eh, to działa dla mnie. – Blender

1

Generator?

def get_next_id(): 
    curr_id = 1 
    while True: 
     yield curr_id 
     curr_id += 1 
3

Oto sposób zliczania instancji bez klas potomnych o tym samym id/count. Metaclass służy do tworzenia oddzielnego licznika identyfikatorów dla każdej klasy.

Stosuje składnię Python 3 dla Metaclasses.

import itertools 

class InstanceCounterMeta(type): 
    """ Metaclass to make instance counter not share count with descendants 
    """ 
    def __init__(cls, name, bases, attrs): 
     super().__init__(name, bases, attrs) 
     cls._ids = itertools.count(1) 

class InstanceCounter(object, metaclass=InstanceCounterMeta): 
    """ Mixin to add automatic ID generation 
    """ 
    def __init__(self): 
     self.id = next(self.__class__._ids) 
0

To powinno załatwić sprawę:

class Obj: 
    _counter = 0 
    def __init__(self): 
     Obj._counter += 1 
     self.id = Obj._counter