Python描述符对象中存储的状态如何在描述符之外访问?

3

能否访问存储在Python描述符中的状态?

例如:

class Price(object):
    def __init__(self, dollars):
        self.dollars = dollars

    class Convert(object):
        def __init__(self, rate):
            self.rate = rate
        def __get__(self, instance, owner):
            return instance.dollars * self.rate
    euros = Convert(0.75)

p = Price(20.0)

print p.dollars
print p.euros

功能正常,但我想获取存储在管理 p.eurosConvert 描述符中的 rate。这可能吗?显然,p.euros.rate 不起作用,但我不确定如何获取 Converter 的 euros 实例。

(我意识到在这个简化的例子中,将欧元作为属性并将汇率放在价格上是有意义的,这只是一个简单的例子)

2个回答

3
实际上,@yak在他自己的答案评论中提供了正确的方法:使用类__dict__属性。因此,您可以通过执行以下操作(在您的代码上,将p列为Price的实例)来获取描述符:p.__class__.__dict__["euros"]。然而请注意,描述符本身是一个“类变量” - 因此,在您的示例中,如果您需要不同的“Price”对象在“欧元”属性上具有不同的“汇率”属性,则Convert描述符必须将“汇率”保留在传递给“__get__”和“__set__”方法的“实例”参数的某个(可能是名称混淆的)属性中。如果是这种情况,您可以直接访问实例本身上的该属性 - 或者在描述符的类本身中实现一些“getter”和“setter”(或嵌套属性),以处理您想要在描述符的属性中操纵的内容。

访问__dict__可以完成任务,但这是不符合Python风格的,也不是描述符的预期使用方式。只是说一下。 - yak
1
评估__dict__是获取描述符对象的唯一方法,它不是实现细节 - 语言规范规定了获取对象和类属性的方式。因此,这并没有什么“非Python式”的东西。 - jsbueno

2

如果通过类访问描述符,则__get__instance参数将为None。您可以检查并返回描述符本身:

class Price(object):
    def __init__(self, dollars):
        self.dollars = dollars

    class Convert(object):
        def __init__(self, rate):
            self.rate = rate

        def __get__(self, instance, owner):
            if instance is None:
                # Accessed through class, return the descriptor instead.
                return self
            return instance.dollars * self.rate

    euros = Convert(0.75)

然后,您可以通过以下方式获取费率:
>>> Price.euros.rate
0.75

有什么想法可以在不对描述符的实现做出任何假设的情况下获取它吗? - Finn
2
@Finn Price.__dict__['euros'].rate 这样做有点取巧。如果可能的话,您应该真正修复您的描述符。 - yak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接