Python:常量类

Python:常量类,python,class,enums,Python,Class,Enums,我在看这个问题的答案: 我最感兴趣的是伊桑·弗曼的回答中的持续类 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

我在看这个问题的答案:

我最感兴趣的是伊桑·弗曼的回答中的持续类

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)
问题是关于Python3.4的,但我使用的是2.7。在答案中,Ethan将引力常数设置为行星类的实例变量,如下所示:

G = Constant(6.67300E-11)
我在2.7中对这个类的测试表明,只需键入G就可以得到:

Out[49]: Constant(3)
(为了便于测试时使用,我将其设置为3。这看起来像是给我的
\uuu repr\uuu
输出,如果我错了,请纠正我。)

该值可通过G.value获得。然而,在Ethan的回答中,他使用了

return self.G * self.mass / (self.radius * self.radius)
这显然只在返回值与
\uu repr\uuu
输出相对时有效。现在如果我将
类常量:
更改为
类常量(int):
然后键入G,我仍然会得到
\uu repr\uu
输出,但如果键入
G*4
我会得到
12
而不是我得到的错误。(TypeError:不支持*:'instance'和'int'的操作数类型) )

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


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

好吧,
是您的
类常量的成员,因此您可以尝试:

另一种方法可以如下


试试看,现在就让我来。希望我能帮助你!

你的类常量应该继承自object,成为一个新的Python类

这样常量就是所谓的描述符。简单来说,描述符是一个Python构造,用于定制获取和设置类属性的行为。当描述符的实例被设置为另一个类的属性时,它们非常有用

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

请注意,只有当描述符实例被另一个类属性访问时,才会调用_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
请注意,当直接打印常量实例时,将调用方法_repr__,但当打印为另一个类属性时,将使用方法_get__


你可以在上阅读更多关于描述符的内容。

从我测试的内容来看,只有当它是类变量而不是实例变量时,它才起作用。如果我通过
self.c=Constant(…)将
c=Constant
移动到
\uu init\uuuu
然后我得到了
\uuuuu repr\uuuuu
输出。它仍然是可写的,这对于一个常量来说很好,因为我可以用所有的大写字母命名。理想情况下,我希望找到一种方法,使一个实例变量可以从类内写入,但不能从
\uuu main\uuuuuuuu
脚本外写入。我在PHP中做得很好,但从我的“到目前为止,我已经阅读了Python中不可能的内容。class属性似乎总是可以覆盖的。ThxI还没有尝试过这个方法,但是您提供的代码对我来说不起作用,因为它是自己的实例。我无法再直接获取值。我怀疑这是因为@baxeico说它必须成为clas中的描述符s、 THX配方似乎有效。但是,它必须驻留在文件中并被导入。它似乎也是一个单例。在类中导入它(就在类定义下方)不会将其限制在该类的命名空间中。也不会将导入行放入
\uuuu init\uuuu
中。如果您能够接受这些限制,那么该方法非常有效。为什么希望它是常量?@Veedrac为什么我不希望常量?或者类中的只读值?从我对Python的阅读中,我了解到它是计数器Python的“我们都是同意的成年人”"哲学。到目前为止,我真的很喜欢Python,但我认为哲学是一种疏忽。我为自己、我自己和我编程——没有人会读或使用它。在过去15年中用几种语言编写代码后,我学到了一些东西。其中之一是,我可以通过简单地设计一个包含除了类的内部,有些东西是无法更改的。我更想知道的是,在什么级别,你要求它是常量;我的目的是检查你是否可以使用“通过公共接口的常量”,这是做这件事的正确方法,或者你真的希望它是完全恒定的,这是不可能的。另外,与其关心他们是否可以设置
,只需将其命名为
——u值
,就可以将其私有化。这样你就不必担心p̶e̶o̶p̶l̶e̶你自己更改它。@Vedra关于Python,我得到了礼貌的回答,你为什么要做这么愚蠢的事情?就常量而言,我可以接受它们通过公共接口只读。我更希望它们是真正的常量,我可以编写一个类变量,该类变量只能在定义它的类之外读取,但我理解它们在Python中可能不可能使用e。
Constant(3.14)
3.14