我遇到了以下问题。
我的类中有一个视图属性,用于访问配置,如果用户在配置中添加了垃圾,则可以引发ValueError
。
我想写一个方法来检查我的配置文件是否有错误,所以我想我查看列表中的每个属性并尝试访问它的值。因此,我不需要为每个属性复制try-except
。
我尝试了以下代码,当然 - 在创建列表时调用属性,因此在我的尝试之外抛出错误。
我的问题有一个优雅的解决方案吗?
import random
def load_config():
rand_number = random.randint(0, 9)
if rand_number == 5:
raise ValueError
return rand_number
class foo:
@property
def bar1(self):
return load_config()
@property
def bar2(self):
return load_config()
@property
def bar3(self):
return load_config()
@property
def bar4(self):
return load_config()
@property
def bar5(self):
return load_config()
def check_properties(self):
properties = [
self.bar1, //Exceptions are thrown here
self.bar2,
self.bar3,
self.bar4,
self.bar5,
]
for property in properties:
try:
num = property
except ValueError:
print("ValueError at " + property.__name__)
my_foo = foo()
my_foo.check_properties()
要制作一个mve,我通过调用函数替换了属性体,并创建了一个随机ValueError
答案 0 :(得分:1)
您可以使用以下内容定义check_properties
:
def check_properties(self):
properties = [property_name for property_name, obj in self.__class__.__dict__.items()
if isinstance(obj, property)]
for property_name in properties:
try:
getattr(self, property_name)
except ValueError:
print("ValueError at " + property_name)
它将尝试评估getattr
中的属性。
这不适用于基类继承的属性。如果你使用继承,你可以使用这样的辅助函数:
def get_property_names(cls, follow_inheritance=False):
property_names = []
for attr_name, attr in cls.__dict__.items():
if isinstance(attr, property):
property_names.append(attr_name)
if follow_inheritance:
for parent_class in cls.__mro__:
if parent_class != cls:
property_names.extend(get_property_names(parent_class, True))
return property_names
然后将check_properties
定义为:
def check_properties(self):
properties = get_property_names(self.__class__, follow_inheritance=True)
for property_name in properties:
try:
getattr(self, property_name)
except ValueError:
print("ValueError at " + property_name)