所以我有这个示例代码,其中Foo是非常动态的数据结构。
def fetch():
# simulate api request
return {'param1':1, 'param2':{'description':'param2', 'value':2}}
class Foo(object):
def __init__(self):
self._rawdata = fetch()
#set attributes accordingly to the downloaded data
for key, val in self._rawdata.items():
setattr(self, key, val)
def __str__(self):
# just an example
out = ''
for key, val in self._rawdata.items():
out += key + ': ' + str(val) + '\n'
return out
用户可能想尝试这样做:
f = Foo()
print(f.param3)
用户不知道' param3'是否存在(API可能没有任何数据可用,在这种情况下,它根本不会提供密钥) 当然,这会导致引发AttributeError。
print(f.param3)
AttributeError: 'Foo' object has no attribute 'param3'
我的问题是:是否有一些元编程的神奇方法将Foo()类包装成一些能够使fn,fn.nonexistent_attribute'返回'无'而不是追溯?我真的想避免硬编码预期的属性(如果API改变了怎么办?)。
答案 0 :(得分:3)
实施__getattr__
method;它将被调用所有不存在的属性:
def __getattr__(self, name):
# all non-existing attributes produce None
return None
来自文档:
当属性查找未在通常位置找到属性时调用(即,它不是实例属性,也不在
self
的类树中找到)。name
是属性名称。此方法应返回(计算的)属性值或引发AttributeError
异常。
演示:
>>> def fetch():
... # simulate api request
... return {'param1':1, 'param2':{'description':'param2', 'value':2}}
...
>>> class Foo(object):
... def __init__(self):
... self._rawdata = fetch()
... #set attributes accordingly to the downloaded data
... for key, val in self._rawdata.items():
... setattr(self, key, val)
... def __getattr__(self, name):
... # all non-existing attributes produce None
... return None
...
>>> print(f.param1)
1
>>> f = Foo()
>>> print(f.param3)
None