我来自 C 背景,正在学习 Python。缺乏明确的类型安全令人不安,但我已经习惯了。面对动态语言的所有优点,缺乏内置的基于契约的编程(纯抽象类、接口)是需要习惯的。
但是,无法请求 const-cortectness 让我抓狂!为什么 Python 中没有常量?为什么不鼓励类级常量?
我来自 C 背景,正在学习 Python。缺乏明确的类型安全令人不安,但我已经习惯了。面对动态语言的所有优点,缺乏内置的基于契约的编程(纯抽象类、接口)是需要习惯的。
但是,无法请求 const-cortectness 让我抓狂!为什么 Python 中没有常量?为什么不鼓励类级常量?
C 和 Python 属于两类不同的语言。
前者是静态类型的。后者是动态的。
在静态类型语言中,类型检查器能够推断每个表达式的类型,并在“编译”阶段检查它是否与给定的声明匹配。
在动态类型语言中,所需的类型信息直到运行时才可用。并且表达式的类型可能因一次运行而异。当然,您可以在程序执行期间添加类型检查。这不是在 Python 中做出的选择。这具有允许“鸭子打字”的优势。缺点是解释器无法检查类型的正确性。
关于const关键字。这是一个类型修饰符。限制允许使用的变量(有时修改允许的编译器优化)。在运行时检查动态语言的效率似乎很低。起初分析,这意味着要检查变量是否为每个做作的const 。这可以进行优化,但即便如此,它是否值得受益?
除了技术方面,不要忘记每种语言都有自己的哲学。在 Python 中,通常的选择是支持“约定”而不是“限制”。例如,常量应该全部大写。没有技术强制执行。这只是一个约定。如果您遵循它,您的程序将按照“其他程序员”的预期运行。如果您决定修改“常量”,Python 不会抱怨。但是你应该觉得你在做“错事”。你打破了约定。也许你有你这样做的理由。也许你不应该有。你的责任。
最后一点,在动态语言中,程序的“正确性”更多地是单元测试的责任,而不是编译器的责任。如果你真的很难做到这一步,你会发现一些“代码检查器”。这些是PyLint,PyChecker,PyFlakes ...
我不知道为什么做出这个设计决定,但我个人的猜测是没有明确的 const 关键字,因为常量的主要好处已经可用:
常量有利于文档目的。如果你看到一个常数,你就知道你不能改变它。这也可以通过命名约定来实现。
常量对于函数调用很有用。如果将常量作为参数传递给函数,则可以确保它不会被更改。在 Python 中,函数是“按值调用”,但由于 Python 变量是引用,因此您可以有效地传递引用的副本。在函数内部,您可以改变引用,但如果重新分配它,更改不会在函数范围之外持续存在。因此,如果您将数字作为变量传递,它实际上是“像”常量一样传递的。您可以为变量分配一个新值。但在函数之外,你仍然得到旧号码
此外,如果有 const 关键字,则会造成不对称:变量声明时没有关键字,而 const 声明时有关键字。合乎逻辑的结果是创建第二个名为 var 的关键字。这可能是一个品味问题。我个人更喜欢变量声明的简约方法。
如果您使用像元组这样的不可变数据结构,您可能可以获得更多的类型安全性。但是要小心,元组本身不能被修改。但是如果它包含对可变对象的引用,即使它们属于元组,它们仍然是可变的。
最后你可能想看看这个片段:http ://code.activestate.com/recipes/65207-constants-in-python/?in=user-97991 我不确定这是否是“类级常量”。但我认为它可能有用。