我一直在寻找这个问题的答案:
Is it possible to define a class constant inside an Enum?

最让我感兴趣的是Ethan Furman的答案中的Constant课。

class Constant:
    def __init__(self, value):
        self.value = value
    def __get__(self, *args):
        return self.value
    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.value)

问题是关于Python 3.4,但我使用的是2.7。在答案中,Ethan将引力常数设置为Planet类的实例变量,如下所示:
G = Constant(6.67300E-11)

我在2.7中对该类的测试表明,仅输入G即可得到以下信息:
Out[49]: Constant(3)

(为了方便测试,我将其设置为3。这看起来像__repr__输出给我,如果我错了,请更正我。)

该值可通过G.value获得。但是,在Ethan的回答中,他使用了
return self.G * self.mass / (self.radius * self.radius)

显然,只有返回值与__repr__输出时,这才有效。现在,如果我将class Constant:更改为class Constant(int):,然后键入G,我仍然会得到__repr__输出,但是如果我键入G * 4,则会得到12,而不是我得到的错误。 (TypeError:*:'instance'和'int'不支持的操作数类型
)

所以很明显,像int对象这样的东西在被调用时可以输出一个数字。我是否缺少一种魔术方法,可以让我对Constant类进行此操作?因为常量可以是字符串,整数或浮点数,所以我更希望有1个类来处理所有常量,而不是3个单独的类来扩展这些对象。

该值也可以通过G.value设置。我可以将其锁定为常量类,使其表现得像实际的常量吗? (我怀疑答案是否定的。)

最佳答案

您的类Constant应该从object继承,成为一种新的Python类。

这样,Constant将成为所谓的描述符。简而言之,描述符是一种Python构造,用于自定义获取和设置类属性的行为。当描述符的实例设置为另一个类的属性时,它们很有用。

在您的示例中,常量是描述符,Planet具有一个属性,该属性是Constant的实例。当您获得Planet类的属性G(在示例中为self.G)时,真正得到的是描述符的__get__方法返回的值。

请注意,仅当描述符实例由另一个类属性访问时才调用__get__。

因此,定义这样的类:

class Constant(object):
    def __init__(self, value):
        self.value = value
    def __get__(self, *args):
        return self.value
    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, self.value)

然后这个小例子:
c = Constant(3.14)
print c

class Test:
    c = Constant(3.14)

t = Test()
print t.c

将打印:
Constant(3.14)
3.14

看到当直接打印Constant实例时,将调用__repr__方法,但是当作为另一个类属性打印时,将使用__get__。

您可以在this great article上阅读有关描述符的更多信息。

关于python - Python:常量类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26067911/

10-10 21:16