用类函数更新字典

2024-09-27 00:18:44 发布

您现在位置:Python中文网/ 问答频道 /正文


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

首先,我尝试在类外更新dict:

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

哦,天哪,为什么这不管用


Tags: nameselfcomnonedbindexlenconsumer
3条回答

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

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就是这样的

这是另一种做事的方法。这会将所有内容移到__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'}}

正如@quamrana指出的,您的代码一直在重用self.args的同一个副本。另一个快速而肮脏的修复方法是在insert之后立即重置self.args

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

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

顺便问一下,dunder(双下划线)是怎么回事

相关问题 更多 >

    热门问题