2016-01-11 13 views
5

Ich habe eine Klasse GenericMake Unterklasse hat ihre eigene Klasse Attribut

class Generic: 
    raw_data = [] 
    objects = dict() 

und konkrete Klassen

class A(Generic): 
    raw_data = module.somethingA 

class B(Generic): 
    raw_data = module.somethingB 

Ich mag jeden raw_data auf jedes objects dict der Klasse füllen. Zu diesem , ich bin mit:

for object_type in (A, B): 
    for data in object_type.raw_data: 
     new_object = object_type(*data) 
     object_type.objects[id(new_object)] = new_object 

Dies ist jedoch nicht funktioniert, weil objects zwischen A und B geteilt wird, und ich wollte jede Unterklasse von Generic ihre eigenen Objekte haben.

Wie erreiche ich dies, ohne objects = dict() für jede Unterklasse eingeben zu müssen?

Ich bin geneigt zu sagen, dass dies ein traditioneller Fall ist, in dem eine Meta-Klasse erforderlich ist (die jeder neuen Klasse objects hinzufügt); Ist das der Fall oder gibt es eine einfachere Option?

Antwort

2

Verwenden Sie entweder eine Metaklasse oder verwenden Sie einen Klassendekorator.

Eine Klasse Dekorateur einfach das Attribut schaffen könnte:

def add_objects(cls): 
    cls.objects = {} 
    return cls 

@add_objects 
class A(generic): 
    raw_data = module.somethingA 

Das ist wirklich etwas hinzufügen, jedoch nicht; Sie ersetzen nur eine Zeile (objects = {}) durch eine andere (@add_objects).

könnten Sie fügen Sie einfach das Objekt in der Schleife:

for object_type in (A, B): 
    if 'objects' not in vars(object_type): 
     object_type.objects = {} 
    for data in object_type.raw_data: 
     new_object = object_type(*data) 
     object_type.objects[id(new_object)] = new_object 

oder kopieren (das Attribut Lesen kann die übergeordnete Klasse Attribut oder eine direkte Attribut abrufen, es keine Rolle, hier der Fall ist):

for object_type in (A, B): 
    object_type.objects = object_type.objects.copy() 
    for data in object_type.raw_data: 
     new_object = object_type(*data) 
     object_type.objects[id(new_object)] = new_object 

oder das Wörterbuch von Grund auf neu erstellen:

for object_type in (A, B): 
    object_type.object = { 
     id(new_object): new_object 
     for data in object_type.raw_data 
     for new_object in (object_type(*data),)} 
1

ich glaube nicht eine Metaklasse necessa ist ry hier. Warum nicht einfach die übergeordneten Klassenobjekte vor dem Auffüllen jeder Unterklasse in der Schleife kopieren?

for object_type in (A, B): 
    # copy Generic.objects onto object_type.objects here 
    object_type.objects = Generic.objects.copy() 
    for data in object_type.raw_data: 
     new_object = object_type(*data) 
     object_type.objects[id(new_object)] = new_object 

Zusätzlich können Sie ändern super und/oder deepcopy zu verwenden, wenn Sie wollen.

Verwandte Themen