2017-12-28 4 views
1


Ich versuche, ein CRM in Python als ein abschließendes Projekt zu einem Kurs zu erstellen.
Und ich erstelle ein Wörterbuch, um wie eine "Datenbank" Form meines CRM zu verwenden.Aktualisieren eines Wörterbuchs mit einer Klassenfunktion

Zuerst tryed ich Aktualisierung der dict außerhalb einer Klasse:

index_db = {} 

index_db[len(index_db)] = {'name_first': 'Johnny', 'name_last': 'Quest', 'email': '[email protected]', 'phone': '1 365 999999999'} 
index_db[len(index_db)] = {'name_first': 'Scooby', 'name_last': 'Doo', 'email': '[email protected]', 'phone': '1 365 888888888'} 
index_db[len(index_db)] = {'name_first': 'Homer', 'name_last': 'Simpson', 'email': '[email protected]', 'phone': '1 365 777777777'} 

Und es Rückkehr:

{ 
    0: { 
     'name_first': 'Johnny', 
     'name_last': 'Quest', 
     'email': '[email protected]', 
     'phone': '1 365 999999999' 
    }, 
    1: { 
     'name_first': 'Scooby', 
     'name_last': 'Doo', 
     'email': '[email protected]', 
     'phone': '1 365 888888888' 
    }, 
    2: { 
     'name_first': 'Homer', 
     'name_last': 'Simpson', 
     'email': '[email protected]', 
     'phone': '1 365 777777777' 
    } 
} 

Es ist gut aussehen, so habe ich eine Klasse:

class Consumer(object): 
    index_db = {} 
    args = {'name_first': None, 'name_last': None, 'email': None, 'phone': None} 

    def __set__(self, var, val): 
     self.args[var] = val 

    def __insert__(self): 
     self.index_db[len(self.index_db)] = self.args 

Und fügen Sie drei Verbraucher ein:

consumer = Consumer() 

consumer.__set__('name_first', 'Johnny') 
consumer.__set__('name_last', 'Bravo') 
consumer.__set__('email', '[email protected]') 
consumer.__set__('phone', '1 353 30316541') 
consumer.__insert__() 

consumer.__set__('name_first', 'Dexter') 
consumer.__set__('name_last', 'Scientist') 
consumer.__set__('email', '[email protected]') 
consumer.__set__('phone', '1 353 33256001') 
consumer.__insert__() 

consumer.__set__('name_first', 'Barney') 
consumer.__set__('name_last', 'Gumble') 
consumer.__set__('email', '[email protected]') 
consumer.__set__('phone', '1 353 555961533') 
consumer.__insert__() 

Und es ist zurück:

{ 
    0: { 
     'email': '[email protected]', 
     'name_first': 'Barney', 
     'name_last': 'Gumble', 
     'phone': '1 353 555961533'}, 
    1: { 
     'email': '[email protected]', 
     'name_first': 'Barney', 
     'name_last': 'Gumble', 
     'phone': '1 353 555961533'}, 
    2: { 
     'email': '[email protected]', 
     'name_first': 'Barney', 
     'name_last': 'Gumble', 
     'phone': '1 353 555961533' 
    } 
} 

Oh Gott, warum tut das nicht?

+1

Es ist, weil Sie Elemente innerhalb des gleichen Wörterbuchs, "args", das Sie einmal als Klassenmitglied erstellen, überschreiben. – quamrana

+1

Alle Ihre 'Consumer'-Objekte teilen sich ein einzelnes Wörterbuch, wenn Sie eines ändern, ändern Sie alle. Definieren Sie eine Methode "__init__". Das richtet stattdessen Instanzvariablen ein. –

Antwort

1

A quick and dirty fix ist dies:

import copy 
class Consumer(object): 
    index_db = {} 
    args = {'name_first': None, 'name_last': None, 'email': None, 'phone': None} 

    def __set__(self, var, val): 
     self.args[var] = val 

    def __insert__(self): 
     self.index_db[len(self.index_db)] = self.args 
     Consumer.args = copy.deepcopy(self.args) 

Die deepcopy erstellt ein neues Wörterbuch für Sie.

Wirklich, Sie brauchen eine bessere Schnittstelle zu Ihrer Klasse.

Und wie @Hai Vu sagt: Was ist mit der dunder Methoden?

Dies könnte besser sein. Und ja, ich weiß, dass es mehr Linien muss verwenden:

class Consumer(object): 
    index_db = {} 

    @classmethod 
    def reset(cls): 
     cls.args = {'name_first': None, 'name_last': None, 'email': None, 'phone': None} 

    @classmethod 
    def set(cls, var, val): 
     cls.args[var] = val 

    @classmethod 
    def insert(cls): 
     cls.index_db[len(cls.index_db)] = cls.args 

consumer = Consumer 

consumer.reset() 
consumer.set('name_first', 'Johnny') 
consumer.set('name_last', 'Bravo') 
consumer.set('email', '[email protected]') 
consumer.set('phone', '1 353 30316541') 
consumer.insert() 

Beachten Sie, dass seit index_db ein Mitglied der Klasse ist, kann das Ganze auch auf Klassenebene sein, so dass das, was mit dem @classmethod s ist.

1

Wie @quamrana darauf hingewiesen hat, wird in Ihrem Code dieselbe Kopie von self.args wiederverwendet. Eine weitere schnelle und unsaubere fix ist self.args direkt nach dem Einsatz zurück:

def __insert__(self): 
     self.index_db[len(self.index_db)] = self.args 
     self.args = {'name_first': None, 'name_last': None, 'email': None, 'phone': None} 

Die letzte Zeile ein neues Wörterbuch erstellt, bereit, gefüllt werden.

Übrigens, was ist mit der dunder (doppelte Unterstriche)?

0

Hier ist ein anderer Weg, Dinge zu tun. Dies verschiebt alles auf die __init__ Methode. Jetzt hat das Consumer ein Attribut index, das aktualisiert wird, wenn ein neues Consumer erstellt wird.

class Consumer(dict): 
    index={} 
    _count=0 
    def __init__(self, first=None, last=None, email=None, phone=None): 
    super().__init__(name_first=first, name_last=last, email=email, phone=phone) 
    Consumer.index[Consumer._count] = self 
    Consumer._count += 1 

jetzt nach

Consumer('Johnny', 'Bravo', '[email protected]', '1 353 30316541') 
Consumer('Dexter', 'Scientist', '[email protected]', '1 353 33256001') 
Consumer('Barney', 'Gumble', '[email protected]', '1 353 555961533') 

Consumer.index wird

{0: {'email': '[email protected]', 
    'name_first': 'Johnny', 
    'name_last': 'Bravo', 
    'phone': '1 353 30316541'}, 
1: {'email': '[email protected]', 
    'name_first': 'Dexter', 
    'name_last': 'Scientist', 
    'phone': '1 353 33256001'}, 
2: {'email': '[email protected]', 
    'name_first': 'Barney', 
    'name_last': 'Gumble', 
    'phone': '1 353 555961533'}} 
0

Danke an alle gleich sein!

Ich folge der @ patrick-Haugh Spitze, und schaffte ein init, der meinen Wörterbuch zu löschen, und rufen Sie den init wieder nach einem Verbraucher ein.

So:

class Consumer(object): 
    index_db = {} 

    def __init__(self): 
    Consumer.args = {'name_first': None, 'name_last': None, 'email': None, 'phone': None} 

    def __set__(self, var, val): 
    self.args[var] = val 

    def __insert__(self): 
    self.index_db[len(self.index_db)] = self.args 
    self.__init__() 

@quamrana Dank für die schmutzig und die kühle Lösung! Ich werde die Schnittstelle meiner Klassen verbessern;)

@ hai-vu: Der Dunder ist, weil ich den Namen set() nicht verwenden kann, so legte ich die doppelten Unterstriche in alle Defs, um einen hässlichen Standard, kkk zu erstellen .

Und noch einmal, vielen Dank!

Verwandte Themen