Reputation: 37
I've been learning how to program and this is problem I'm having trouble solving:
I have a class User that takes 4 parameters, 2 required and 2 optional:
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
then I make a function to create those objects, they take a dictionary and use looks in the keys to create the objects
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'}
so like this it only works if the dictionary given has all the four keys,which is the case of example_userinfo1, but not the case for example_userinfo2 (only ID and first_name are mandatory). I would like to know what is the way of checking if the key exists before passing it as an argument, I tried something like this with no success:
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'])
so what is a good way to overcome this problem? also I would like to know if there are many signs of bad practices on my code (as I am trying to start paying attention to those things)
Upvotes: 0
Views: 364
Reputation: 48100
Better way to do this is to unpack the dict
using **
. For example:
>>> 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>
When you unpack the dict within the function call, it maps the dict
key with the function parameters and the dict value as the value of parameter. So in this case, your function call was like:
User(user_id=222, first_name='bob')
Edit: Based on additional information from user as id
is returned from API. And it is not good to use id
as variable since id()
is built-in function in python. In this case, you can modify dict
explicitly as:
>>> 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
Upvotes: 1
Reputation: 1124070
Make your dictionary keys correspond dir to the argument names, just apply the whole dictionary as keyword arguments:
user_id = user_info.pop('id')
users[user_id] = User(user_id, **user_info)
I used dict.pop()
to remove the 'id'
key as your class expects user_id
instead. You already supplied default values for any missing keys.
Otherwise, you could have used dict.get()
to return an empty string if a key is missing:
User(user_info['id'], user_info['first_name'],
last_name=user_info.get('last_name', ''),
username=user_info.get('username', ''))
Upvotes: 1