为什么不';常数';用Python?

为什么不';常数';用Python?,python,constants,const-correctness,Python,Constants,Const Correctness,我来自C语言背景,正在学习Python。显式类型安全性的缺乏令人不安,但我已经习惯了。面对动态语言的所有优点,缺乏内置的基于契约的编程(纯抽象类、接口)是需要习惯的 然而,无法要求保持一致性让我发疯!为什么Python中没有常量?为什么你会气馁 C和Python属于两类不同的语言 前者是静态类型的。后者是动态的 在静态类型语言中,类型检查器能够推断每个表达式的类型,并在“编译”阶段检查其是否与给定的声明匹配 在动态类型语言中,所需的类型信息在运行时之前不可用。表达式的类型可能因运行的不同而不同。

我来自C语言背景,正在学习Python。显式类型安全性的缺乏令人不安,但我已经习惯了。面对动态语言的所有优点,缺乏内置的基于契约的编程(纯抽象类、接口)是需要习惯的


然而,无法要求保持一致性让我发疯!为什么Python中没有常量?为什么你会气馁

C和Python属于两类不同的语言

前者是静态类型的。后者是动态的

在静态类型语言中,类型检查器能够推断每个表达式的类型,并在“编译”阶段检查其是否与给定的声明匹配

在动态类型语言中,所需的类型信息在运行时之前不可用。表达式的类型可能因运行的不同而不同。当然,您可以在程序执行期间添加类型检查。这不是Python中的选择。这样做的好处是允许“duck-typing”。缺点是解释器无法检查类型正确性

关于const关键字。这是一个类型修饰符。限制允许使用变量(有时修改允许的编译器优化)。对于动态语言,在运行时检查这一点似乎效率很低。在最初的分析中,这意味着要检查每个矫揉造作的变量是否为常量。这是可以优化的,但即便如此,它值得这样做吗

除了技术方面,别忘了每种语言都有自己的哲学。在Python中,通常的选择是支持“约定”而不是“限制”。例如,常量应在所有大写字母中拼写。没有技术上的强制执行。这只是一个惯例。如果您遵循它,您的程序将按照“其他程序员”的预期运行。如果您决定修改一个“常量”,Python不会抱怨。但你应该觉得自己在做“错事”。你打破了惯例。也许你有这样做的理由。也许你不该这么做。你的责任


最后,在动态语言中,程序的“正确性”更多地是单元测试的责任,而不是编译器的责任。如果你真的很难迈出这一步,你会发现一些“代码检查器”。这些是,…

我不知道为什么会做出这个设计决定,但我个人的猜测是,没有明确的const关键字,因为常量的主要好处已经存在:

  • 常量对于文档来说很有用。如果你看到一个常数,你就知道你不能改变它。这也可以通过命名约定实现

  • 常量对于函数调用很有用。如果将常量作为参数传递给函数,则可以确保它不会更改。在Python中,函数是“按值调用”,但由于Python变量是引用,因此可以有效地传递引用的副本。在函数内部,您可以改变引用,但如果重新分配引用,则更改不会在函数范围之外持续。因此,如果你把一个数字作为变量传递,它实际上就像一个常数一样被传递。可以为变量指定一个新值。但是在函数之外,你仍然得到了旧的数字

此外,如果有一个const关键字,它将创建一个不对称性:变量声明时没有关键字,而const声明时有关键字。逻辑结果是创建第二个名为var的关键字。这可能是一个品味问题。就我个人而言,我更喜欢简约的方法,而不是变量声明

如果使用元组之类的不可变数据结构,您可能会实现更多的类型安全性。但是要小心,元组本身不能被修改。但如果它包含对可变对象的引用,即使它们属于元组,它们仍然是可变的


最后,您可能想看看这个代码段:我不确定这是否是“类级常量”的实现。但我认为它可能有用。

“Python中的常量没有等价物,因为程序员通常被认为足够聪明,可以留下一个他想保持常量的值”。因为Python程序员知道他们在做什么,并且不太天真,不会修改应该是常量的变量(在C上下文中)@Vorac,如果继续思考,那么为什么Python中没有
int
double
char
类型呢?。。因为它是动态语言。如果你想“混合”Python和C,你可以看看Cython或者简单地回答:这是一个观点问题。在另一个主题中,LISP程序员曾经说过“内存分配太重要了,不能留给程序员”。“C程序员认为内存分配太重要了,不能留给计算机”(B.Stroustroup)。对于类型/常量的正确性,您可以说完全相同。动态规划是没有限制的。我应该能够很容易地定义y(常数x)。这基本上是“python中的另一个问题:我同意Erik Aronesty的观点——const遵从性可以在”编译“中检查“在许多情况下都需要时间。即使变量的类型仅在运行时确定,也可以保证变量不会在特定上下文中被直接修改。@user3204459我不会争辩,因为我不擅长该领域,但您的建议强烈提醒了我检查和传播变量可能修改的污染分析。使用静态分析,这被证明是正确的。另一方面,您可以添加一些运行时检查,但这会带来明显的开销。第三种方法,可能是我最喜欢的方法,是使每一个数据都是不可变的。@SylvainLeroux是真的,但是一个严密的污染分析可能超出了这里的建议。谦逊的阿尔特