I'm working on a bit of code that takes in dictionaries and creates an instance of an object. While doing some learning on the try
and except
blocks, I have incorporated it into my little function. I've ready many times that checking before doing something isn't Pythonic, so I was wondering how I would alter my code (below) to meet that suggestion. At it stands, the code works only because I use getattr
before setting. Otherwise, setattr
will create the property rather than failing because the property does not exist.
class Gem:
def __init__(self):
self.name = None
self.val = None
class Rock:
def __init__(self):
self.name = None
self.weight = None
def create_objects(data):
obj_list = []
for i in data:
new_obj = Gem()
try:
for k, v in i.items():
getattr(new_obj, k)
setattr(new_obj, k, v)
obj_list.append(new_obj)
except:
print("Fail")
return obj_list
data_list = [
{"name": "Star", "val": 5},
{"name": "Square", "val": 1},
{"name": "Granite", "weight": 50}
]
obj_list = create_objects(data_list)
for o in obj_list:
for k, v in vars(o).items():
print(k, v)
To set attributes when creating instances, pass them as arguments to __init__
. That way, you can be sure that they do not exist yet and you need no try
/ except
:
class Gem:
def __init__(self, name, val):
self.name = name
self.val = val
obj_list = []
for gem_attributes in data_list:
gem = Gem(gem_attributes['name'], gem_attributes['val'])
obj_list.append(gem)
Passing dictionary values as arguments with the same names as the keys can be shortened with the **
argument unpacking syntax:
gem = Gem(**gem_attributes)
And the whole list creation can be shortened to a list comprehension:
obj_list = [
Gem(**gem_attributes)
for gem_attributes in data_list
]
As an additional complication you have different object types.
In order to create both Gem
and Rock
objects in the same loop, I recommend to add the object type explicitly to the input data, instead of relying on the attribute names to distinguish them:
data_list = [
('Gem', {'name': 'Star', 'val': 5}),
...
('Rock', {'name': 'Granite', 'weight': 50})
]
obj_list = []
for obj_type, obj_attributes in data_list:
obj_class = {'Gem': Gem, 'Rock': Rock}[obj_type]
obj_list.append(obj_class(**obj_attributes))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.