如何使用字典中的可选元素列表创建对象?

时间:2016-11-20 20:20:23

标签: python

我一直在学习如何编程,这是我遇到问题时遇到的问题:

我有一个类User,它有4个参数,2个必需和2个可选:

class User:
    def __init__(self, user_id, first_name, last_name='', username=''):
        self.user_id = user_id
        self.first_name = first_name
        self.last_name = last_name
        self.username = username

然后我创建了一个创建这些对象的函数,它们使用字典并使用键中的查找来创建对象

users={}


def user_register(user_info):
if user_info['id'] in users:
    pass
else:
    print('cadastrando...')
    users[user_info['id']] = User(user_info['id'], user_info['first_name'],
                                  user_info['last_name'], user_info['username'])

example_userinfo1 = {'id':111, 'first_name':'john', 'last_name':'smith', 'username':'@johnsmith'}

example_userinfo2 = {'id':222, 'first_name':'bob'}

所以这样它只有在给定的字典具有所有四个键时才有效,例如example_userinfo1,但不是example_userinfo2的情况(只有ID和first_name是必需的)。我想知道在将它作为参数传递之前检查密钥是否存在的方法是什么,我尝试过这样的事情但没有成功:

User(user_info['id'], user_info['first_name'],
        if 'last_name' in user_info: last_name=user_info['last_name'],
        if 'username' in user_info: username=user_info['username'])

那么克服这个问题的好方法是什么?我也想知道我的代码是否有很多不良做法的迹象(因为我试图开始关注这些事情)

2 个答案:

答案 0 :(得分:1)

使你的字典键对应于参数名称的dir,只需将整个字典应用为关键字参数:

user_id = user_info.pop('id')
users[user_id]  = User(user_id, **user_info)

我使用dict.pop()删除'id'密钥,因为您的班级期望user_id。您已经为任何缺失的密钥提供了默认值。

否则,如果缺少密钥,您可以使用dict.get()返回空字符串:

User(user_info['id'], user_info['first_name'],
    last_name=user_info.get('last_name', ''),
    username=user_info.get('username', ''))

答案 1 :(得分:1)

更好的方法是使用dict解包**。例如:

>>> userinfo = {'user_id':222, 'first_name':'bob'}
#                  ^  I am using `user_id` instead of `id`. 
#                     Continue reading for explanation
>>> User(**userinfo)
<__main__.User instance at 0x7f1f4c70cf80>

在函数调用中解压缩dict时,它会将dict键与函数参数和dict值映射为参数值。所以在这种情况下,你的函数调用就像:

User(user_id=222, first_name='bob')

修改:基于来自API的用户提供的id的其他信息。将id用作变量并不好,因为id()是python中的内置函数。在这种情况下,您可以明确地将dict修改为:

>>> userinfo = {'id':222, 'first_name':'bob'}
>>> userinfo['user_id'] = userinfo['id']
>>> del userinfo['id']
>>> userinfo
{'first_name': 'bob', 'user_id': 222}   # Final value hold by dict