1


I'm trying to create a CRM in Python as a final project to a course.
And I create a dictionary to use like a "database" form my CRM.

First, I tryed update the dict outside a class:

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'} 

And it's return:

{ 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' } } 

It's look great, so I created a class:

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 

And insert three consumers:

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

And it's return:

{ 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 God, why does not this work?

2
  • 1
    Its because you keep overwriting elements within the same dictionary, args, which you create once as a class member. Commented Dec 28, 2017 at 17:13
  • 1
    All your Consumer objects share a single dictionary, whenever you change one of them, you change all of them. Define an __init__ method. that sets up instance variables instead. Commented Dec 28, 2017 at 17:14

4 Answers 4

1

As @quamrana pointed out, your code keep reusing the same copy of self.args. Another quick-and-dirty fix is to reset self.args right after insert:

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

The last line creates a new dictionary, ready to be populated.

By the way, what's with the dunder (double underscores)?

Sign up to request clarification or add additional context in comments.

Comments

1

A quick and dirty fix is this:

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) 

The deepcopy creates a new dictionary for you.

Really, you need a better interface to your class.

And as @Hai Vu says: What's with the dunder methods?

This might be better. And yes, I know it needs more lines to use:

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

Note that since index_db is a member of the class, the whole thing might as well be at the class level, so that's what's with the @classmethod s.

Comments

1

Here's another way of doing things. This moves everything to the __init__ method. Now the Consumer has an attribute index that it updates whenever a new Consumer is created.

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 

now after

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 will be equal to

{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'}} 

Comments

0

Thanks everyone!

I follow the @patrick-haugh tip, and created a init who clear my dictionary, and call the init again after insert a consumer.

Like this:

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 thanks for the dirty and the cool solution! I will improve the interface of my classes ;)

@hai-vu: The dunder is because I can't use the name set(), so i put the double underscores in all defs to create a ugly default, kkk.

And again, thanks everyone!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.