使用Python反射式获取字段名

使用Python反射式获取字段名,python,reflection,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”) 不太可能。事物甚至可能没有名称-什么是: validat

是否可以在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”

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

validator.max(3,10)
该怎么办

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

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

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

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

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
    ...

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

但是,您可以将验证逻辑移动到更高的级别(基类),并使其在整个对象上工作。通过这种方法,validate函数将知道验证器“名称”,并可用于错误消息:

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)
类验证对象:
def验证(自我):
对于目录中的名称(self):
如果(name.startswith(“validate”)和#是验证器
未获取属性(self,name)():#并且失败
引发运行时错误(“%s:%s”%)
(名称,getattr(self,name)。\uuuu doc\uuuuuu)
为某个对象初始化(ValidatedObject):
定义初始化(self,x,y):
self.x=x
self.y=y
def validate_x(自身):
“水平位置不应该那么大”
返回self.x<10
def验证_y(自身):
“垂直位置不得过低或过高”

返回20另外,函数参数在调用函数之前进行求值。
self.x
x
有点多余。FWIW
validate()
可以修改为在构造错误消息时提取并使用方法名的
“validate”
后面的文本。DRY.@martineau:
\uuuu doc\uuuu
的使用不是重复,它可能是一条与验证器名称无关的用户友好消息。验证程序的名称已在
之前的消息中使用(但不会删除
“validate”
)。我将添加一个编辑,以使意图更加清晰……我对使用
\uuuuu doc\uuuu
字符串没有问题——只是提出了一个建议,允许它更符合OP问题中所述的“获取字段名称”。您所想到的不仅仅是简单的字段值验证(这是一件好事,IMHO)。