使用类函数更新字典

时间:2017-12-28 17:09:47

标签: python dictionary


我正在尝试用Python创建一个CRM作为课程的最终项目。
我创建了一个字典,就像我的CRM中的“数据库”一样。

首先,我尝试在课堂外更新字典:

index_db = {}

index_db[len(index_db)] = {'name_first': 'Johnny', 'name_last': 'Quest', 'email': 'jquest@cartoonville.com', 'phone': '1 365 999999999'}
index_db[len(index_db)] = {'name_first': 'Scooby', 'name_last': 'Doo', 'email': 'sdoo@cartoonville.com', 'phone': '1 365 888888888'}
index_db[len(index_db)] = {'name_first': 'Homer', 'name_last': 'Simpson', 'email': 'hsimpson@cartoonville.com', 'phone': '1 365 777777777'}

它的回归:

{
    0: {
        'name_first': 'Johnny',
        'name_last': 'Quest',
        'email': 'jquest@cartoonville.com',
        'phone': '1 365 999999999'
    },
    1: {
        'name_first': 'Scooby',
        'name_last': 'Doo',
        'email': 'sdoo@cartoonville.com',
        'phone': '1 365 888888888'
    },
    2: {
        'name_first': 'Homer',
        'name_last': 'Simpson',
        'email': 'hsimpson@cartoonville.com',
        'phone': '1 365 777777777'
    }
}

看起来很棒,所以我创建了一个类:

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

consumer.__set__('name_first', 'Johnny')
consumer.__set__('name_last', 'Bravo')
consumer.__set__('email', 'jbravo@cartoonville.com')
consumer.__set__('phone', '1 353 30316541')
consumer.__insert__()

consumer.__set__('name_first', 'Dexter')
consumer.__set__('name_last', 'Scientist')
consumer.__set__('email', 'dscientist@cartoonville.com')
consumer.__set__('phone', '1 353 33256001')
consumer.__insert__()

consumer.__set__('name_first', 'Barney')
consumer.__set__('name_last', 'Gumble')
consumer.__set__('email', 'bgumble@cartoonville.com')
consumer.__set__('phone', '1 353 555961533')
consumer.__insert__()

它的回归:

{
    0: {
        'email': 'bgumble@cartoonville.com',
        'name_first': 'Barney',
        'name_last': 'Gumble',
        'phone': '1 353 555961533'},
    1: {
        'email': 'bgumble@cartoonville.com',
        'name_first': 'Barney',
        'name_last': 'Gumble',
        'phone': '1 353 555961533'},
    2: {
        'email': 'bgumble@cartoonville.com',
        'name_first': 'Barney',
        'name_last': 'Gumble',
        'phone': '1 353 555961533'
    }
}

天啊,为什么这不起作用?

4 个答案:

答案 0 :(得分:1)

快速而肮脏的解决方法是:

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)

deepcopy为您创建一个新词典。

真的,你需要一个更好的班级接口。

正如@Hai Vu所说: dunder 方法有什么用?

这可能会更好。是的,我知道它需要更多的线路使用:

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', 'jbravo@cartoonville.com')
consumer.set('phone', '1 353 30316541')
consumer.insert()

请注意,由于index_db是该类的成员,因此整个事情也可能属于类级别,因此这与@classmethod的内容相同。

答案 1 :(得分:1)

正如@quamrana指出的那样,您的代码不断重用.then(() =>的同一副本。另一个快速而又脏的修复方法是在插入后立即重置self.args

self.args

最后一行创建一个新词典,准备填充。

顺便说一句, dunder (双重下划线)是什么?

答案 2 :(得分:1)

这是另一种做事方式。这会将所有内容移动到__init__方法。现在Consumer有一个属性index,只要创建了新的Consumer,它就会更新。

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

现在

之后
Consumer('Johnny', 'Bravo', 'jbravo@cartoonville.com', '1 353 30316541')
Consumer('Dexter', 'Scientist', 'dscientist@cartoonville.com', '1 353 33256001')
Consumer('Barney', 'Gumble', 'bgumble@cartoonville.com', '1 353 555961533')

Consumer.index将等于

{0: {'email': 'jbravo@cartoonville.com',
     'name_first': 'Johnny',
     'name_last': 'Bravo',
     'phone': '1 353 30316541'},
 1: {'email': 'dscientist@cartoonville.com',
     'name_first': 'Dexter',
     'name_last': 'Scientist',
     'phone': '1 353 33256001'},
 2: {'email': 'bgumble@cartoonville.com',
     'name_first': 'Barney',
     'name_last': 'Gumble',
     'phone': '1 353 555961533'}}

答案 3 :(得分:0)

谢谢大家!

我按照@ patrick-haugh提示,创建了一个清除字典的 init ,并在插入消费者后再次调用 init

像这样:

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感谢脏和酷的解决方案!我将改进我的类的接口;)

@ hai-vu:dunder是因为我不能使用名字set(),所以我在所有defs中加上双下划线来创建一个丑陋的默认值,kkk。

再一次,谢谢大家!