循环遍历属性列表

时间:2016-02-15 19:46:25

标签: python list python-3.x properties

我遇到了以下问题。 我的类中有一个视图属性,用于访问配置,如果用户在配置中添加了垃圾,则可以引发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

1 个答案:

答案 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)