在Python类中,我必须对几个私有变量进行多次检查,例如: G。列表中包含的self.__a
,self.__b
和self.__c
。然后程序就像这样开始:
for var in [self.__a, self.__b, self.__c]:
...
我现在的问题是,列表中包含的一些(可能是所有)变量现在可能尚未设置,并且我的程序因发生AttributeError
而停止。
我想出设置这个列表以便它只包含已经存在的变量的唯一方法就是写(在这种情况下是三个)try-except-clause,其中每一个都将一个变量添加到名单。但我认为必须有更好的方法来解决这个问题。
我怎样才能以更优雅的方式做到这一点?
答案 0 :(得分:3)
您可以修改班级中的__getattr__
方法,以防止在这些情况下返回AttributeError
,la:
class Foo(object):
def __getattr__(self, name):
if hasattr(self, name):
return object.__getattr__(self, name)
else:
return None
显然,您可以将此扩展到name
位于["__a", "__b", "__c"]
或startswith("__")
的情况。
然后在类似于之前的方法中使用,但过滤掉None
s:
for var in filter(None, [self.__a, self.__b, self.__c]):
...
注意:如果你知道它在做什么,你应该真正做到这一点,并且你了解它带来的风险。在大多数情况下,您应该try-except
并在AttributeError
上寻求宽恕。
答案 1 :(得分:1)
你可以这样做:
for attr in ['__a', '__b', '__c']:
try:
var = getattr(self, attr)
# Do something
except AttributeError:
pass # or do something else
你也可以这样做:
NON_EXISTING = object() # put this as a global variable somewhere for reusability
for attr in ['__a', '__b', '__c']:
var = getattr(self, attr, NON_EXISTING)
if var is not NON_EXISTING:
# Do something
else: # If you just want to skip, you will not even need this
pass # or do something else
或者这个:
for attr in ['__a', '__b', '__c']:
if hasattr(self, attr):
var = getattr(self, attr)
# Do something
else:
pass # or do something else
答案 2 :(得分:0)
与您所做的相似的事情,即写三个try/except
,如果它存在则获取值,否则使用getattr
。
obj = MyObject()
for var_name in ["__a", "__b", "__c"]:
var = getattr(obj, var_name, None)
if var is not None:
do_stuff()
我更喜欢这个解决方案,而不是在被要求检索任何属性时修改对象的行为方式,因为@IanClark建议的答案