使用Python反射性地获取字段名称

时间:2011-04-28 11:56:01

标签: python reflection

是否可以在Python(3.2)中反射性地获取字段的名称?

请参阅以下示例:

class Something:
    def __init__(self):
        self.x = 1

    def validate():
        return validator.max(self.x, 10)

validator.max(self.x, 10)应生成包含字段x名称的错误消息(在本例中为"x")。

3 个答案:

答案 0 :(得分:5)

您必须将属性名称作为字符串

传递
def validate():
    return validator.max(self, "x", 10)

然后validator.max可能看起来像这样

def max(ob, attr, max_value):
    val = getattr(ob, attr)    # val would be self.x now
    ...

答案 1 :(得分:2)

不太可能。事情甚至可能没有名字 - 是什么:

validator.max(3,10)

应该做什么?

如果要输出名称,请传递名称和值:

validator.max(self.x,10,"x")

无论validator.max是什么,它需要另一个参数,或者如果它是内置的,你需要包装它。

答案 2 :(得分:2)

在Python中,表达式self.x只是该成员的当前值,因此该值来自对象的信息将丢失。

但是,您可以将验证逻辑移动到更高级别(基类)并使其处理整个对象。使用此方法验证函数将知道验证器“name”,并可用于错误消息:

class ValidatedObject:
    def validate(self):
        for name in dir(self):
            if (name.startswith("validate_") and  # Is a validator
                not getattr(self, name)()):       # and failed
                raise RuntimeError("%s: %s" %
                                   (name, getattr(self, name).__doc__))

class Something(ValidatedObject):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def validate_x(self):
        "Horizontal position shouldn't be that big"
        return self.x < 10

    def validate_y(self):
        "Vertical position must be neither too low nor too high"
        return 20 <= self.y <= 30

    def validate_sum(self):
        "The position must be on the prescribed line"
        return self.x + self.y == 25

class Something2(Something):
    def validate_sum(self):
        return True

Something(3, 22).validate()   # Ok
Something2(5, 30).validate()  # Ok (derived class relaxed checks)
print "About to crash...."
Something2(5, 31).validate()  # Not ok (Y is too high - inherited check)

当然,请注意,从IS-A的角度来看禁用派生类中的检查是不合逻辑的,这里只是一个示例,表明dir将正确地找到继承的成员。