try/except 设置对象变量的 Pythonic 方式
Pythonic way of try/except setting of object variables
我正在编写一些代码,这些代码接受字典并创建一个对象的实例。在对 try
和 except
块进行一些学习时,我已将其合并到我的小函数中。我已经多次准备好在做某事之前进行检查不是 Pythonic,所以我想知道我将如何更改我的代码(如下)以满足该建议。就目前而言,代码之所以有效,是因为我在设置之前使用了 getattr
。否则,setattr
将创建 属性 而不是因为 属性 不存在而失败。
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)
要在创建实例时设置属性,将它们作为参数传递给 __init__
。这样,您可以确定它们还不存在,并且您不需要 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)
可以使用 **
参数解包语法缩短将字典值作为与键同名的参数传递:
gem = Gem(**gem_attributes)
并且整个列表创建可以缩短为列表理解:
obj_list = [
Gem(**gem_attributes)
for gem_attributes in data_list
]
作为一个额外的并发症,您有不同的对象类型。
为了在同一个循环中同时创建Gem
和Rock
对象,我建议将对象类型显式添加到输入数据中,而不是依靠属性名称来区分它们:
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))
我正在编写一些代码,这些代码接受字典并创建一个对象的实例。在对 try
和 except
块进行一些学习时,我已将其合并到我的小函数中。我已经多次准备好在做某事之前进行检查不是 Pythonic,所以我想知道我将如何更改我的代码(如下)以满足该建议。就目前而言,代码之所以有效,是因为我在设置之前使用了 getattr
。否则,setattr
将创建 属性 而不是因为 属性 不存在而失败。
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)
要在创建实例时设置属性,将它们作为参数传递给 __init__
。这样,您可以确定它们还不存在,并且您不需要 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)
可以使用 **
参数解包语法缩短将字典值作为与键同名的参数传递:
gem = Gem(**gem_attributes)
并且整个列表创建可以缩短为列表理解:
obj_list = [
Gem(**gem_attributes)
for gem_attributes in data_list
]
作为一个额外的并发症,您有不同的对象类型。
为了在同一个循环中同时创建Gem
和Rock
对象,我建议将对象类型显式添加到输入数据中,而不是依靠属性名称来区分它们:
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))