我一直在学习如何编程,这是我遇到问题时遇到的问题:
我有一个类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'])
那么克服这个问题的好方法是什么?我也想知道我的代码是否有很多不良做法的迹象(因为我试图开始关注这些事情)
答案 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