2011-12-25 25 views
10

he estado limpiando algo de código de un módulo de E extiendo y me parece que no puede encontrar una manera de Pythonify este código:¿Contando instancias de una clase?

global_next_id = 1 

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

    global_next_id += 1 

Este código utiliza un identificador global para realizar un seguimiento de los casos de una clase (también necesito la variable self.id internamente, y debe ser un número).

¿Alguien puede sugerir una forma de Pythonify este código?

+1

¿Por qué es necesario "un seguimiento de instancias de una clase" con una identificación global? –

+1

Es para una biblioteca PDF que estoy modificando. Cada PDF 'Obj' debe imprimirse con su respectiva ID. – Blender

Respuesta

34

intentar algo como esto:

from itertools import count 

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

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

Totalmente pasé por alto las variables de toda la clase ... ¡Gracias por la solución 'itertools'! – Blender

+1

Ojalá pudiera reclamar el crédito único: lo vi en otro lugar aquí en otra publicación. Es elegante y eficiente. –

+0

Eh, funciona para mí. – Blender

1

Generador?

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

Aquí es una manera de contar los casos sin clases descendientes que comparten el mismo id/recuento. Una metaclase se usa para crear un contador de id. Separado para cada clase.

Utiliza la sintaxis de Python 3 para 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

Esto debería hacer el trabajo:

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