我一直在寻找这个问题的答案:
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/