在Java中,如果我想要“一个不变的变量,它可以用于类中的所有方法,而不作为参数传递”,我会这样做:
public class MyClass {
private static final OtherClass OTHER_CLASS = buildOtherClass()
...
private static OtherClass buildOtherClass() {
//<creation logic>
}
}
但是,如果我尝试在Python脚本中执行类似的操作,就会出现错误:
^{pr2}$如果我将变量声明移到方法声明下面,代码将按预期运行。但是,对于代码的合法性依赖于元素的排序,我感觉很不直观,-方法存在于文件中,我不明白为什么不能找到它,仅仅因为它“还没有声明”。Moverover,将通用(非特定于方法的)变量放在文件顶部是一种代码约定,我觉得这是非常明智和有帮助的——“下面是我们将要处理的事情的概述”(尽管我想这在Python中并不那么正确,因为在Python中没有类型声明来提供额外的上下文)。在
我可以找到一些方法来解决这个问题,但没有一个在美学上是令人愉悦的:
__init__
方法中初始化变量。同样,这似乎是不必要的开销。在__main__
方法调用的方法中的全局变量,如下面的代码所示。不过,我已经看到很多指导意见,认为全球变量是一个危险信号,所以我想我也应该避免这种情况。在(我需要将文本放在这里,否则下面的代码段是未格式化的,可能是因为上面的项目符号)
$ cat python_test_2.py
#!/usr/bin/env python3
def initializeGlobalVariables():
global DICTIONARY
DICTIONARY = {}
for i in range(5):
DICTIONARY[str(i)] = i
def doOtherLogic():
for key in DICTIONARY:
print('DICTIONARY[' + str(key) + '] is ' + str(DICTIONARY[key]))
def main():
initializeGlobalVariables()
doOtherLogic()
if __name__ == '__main__':
main()
$ ./python_test_2.py
DICTIONARY[0] is 0
DICTIONARY[1] is 1
DICTIONARY[2] is 2
DICTIONARY[3] is 3
DICTIONARY[4] is 4
可能是因为我所要做的是完全不和谐的,所以缺乏支持是“出于设计”。我从一些经验丰富的用户那里得到了更多关于Python风格的反馈。在
Python和Java在本质上是截然不同的语言,Python更像是一种脚本语言而不是编译语言(尽管它确实是在动态编译的)。而且,Python实际上并没有“不变变量…”的概念,至少没有通过变量名。变量名本质上是指向任何类型数据的指针(请参见:动态类型),如果没有特殊的python修饰符,您可以随时更改变量的值,有时会对您造成很大的损害。在
更重要的是,由于它的脚本性质(并且可以交互执行),事情的顺序很重要:
在本例中,函数
^{pr2}$test
中的全局x
只是一个指针,x
不存在并不重要,因为您还没有尝试运行test
。当来自强类型和编译语言时,这可能看起来与直觉相反,但它允许许多不错的功能,如动态导入,只在使用函数时加载模块:如果每个变量都需要在函数内部使用之前被完全定义,那么定义
dyn_import
将失败,除非random
被加载并且理解random.random()
的含义。在这种情况下,直到函数实际执行时才加载它。另外,由于函数不会将模块放入脚本的全局命名空间中,因此一旦函数完成,模块就会被丢弃。在这只是一个很重要的例子,说明这样做是非常有益的。在
相关问题 更多 >
编程相关推荐