我有一个具有多个属性的Object(从数据库中检索):
db_obj.default_attr= "textdefault"
db_obj.additional = {
"alpha": "texta",
"beta": "textb",
"gama": "textg",
"teta": "textt",
...
}
db_obj.name: "some_name"
....
additional
属性也是一个对象,可以为空/空/不具有所有值,在db中为null或json
然后types
是一个数组:["alpha", "gama", ...]
我具有以下功能,即:
set_att(obj=db_object, types=types)
我需要基于types
数组创建一个新对象:
属性示例:
new_obj.alpha = "texta"
new_obj.gama = "textdefault" # because gama was not found in additional
我定义了函数:
def set_att(db_obj=None, types=None):
new_obj = types.SimpleNamespace()
try:
add = db_obj.getattr(additional)
# cycle thru types, and assign the value from the db_obj if exist or the default_attr value
for item_type in types:
try:
setattr(new_obj, item_type, add.getattr(item_type))
except AttributeError:
setattr(new_obj, item_type, obj.getattr(default_attr))
# if there is not addtional I still set default for type
except AttributeError:
for item_type in types:
setattr(new_obj, item_type, obj.getattr(default_attr)
它看起来很幼稚,我正在寻找一个更Python化的选项。
答案 0 :(得分:2)
您可以使用hasattr
来检查对象是否具有属性,而不是捕获AttributeException。这将使代码更易于阅读,因为它显式地处理了不存在该属性的预期情况。使用异常会使它看起来好像是一个错误情况。
for item_type in types:
if hasattr(add, item_type):
value = getattr(add, item_type)
else:
value = getattr(obj, default_attr)
setattr(new_obj, item_type, value)
答案 1 :(得分:1)
您可以创建一个此类来访问数组键作为对象属性
class CustomDict(dict):
def __getattr__(self, key):
return self[key]
def __getitem__(self, key):
try:
return super(CustomDict, self).__getitem__(key)
except KeyError:
return None
def get(self, key, default=None):
try:
return super(CustomDict, self).__getitem__(key)
except KeyError:
return self.build(default)
@classmethod
def build(cls, orig):
if isinstance(orig, basestring):
return orig
if isinstance(orig, Sequence):
return [cls.build(item) for item in orig]
elif isinstance(orig, Mapping):
new = cls()
for key, value in orig.iteritems():
new[key] = cls.build(value)
return new
return orig
像这样使用::
additional = {
"alpha": "texta",
"beta": "textb",
"gama": "textg",
"teta": "textt",
}
new=CustomDict(additional)
然后您可以访问以下属性:
print(new.alpha) # print texta
print(new.xyz) # print None