2

解决方案:Python 在设置时计算变量的值,而变量只是一个指针。我会说第一个选项更清楚,因为运行时的唯一区别是 Python 需要多长时间才能将值转换为二进制存储 - 最小。

我感谢所有回复的人。

在正在编写的模块中,我需要为简单的开/关开关定义大量常量。这显然很容易作为二进制字符串完成,但是当我定义 constnts 时,下面的哪个方法对运行时速度和运行时内存使用的影响较小。

一:

THIS_VAR_0 = 2**0
THIS_VAR_1 = 2**1
.
.
.
This_Var_N = 2**N

或者,两个:

THIS_VAR_0 = 0
THIS_VAR_1 = 1
.
.
.
This_Var_N = 536870912 # 2**30

编辑:他们不需要计算不止一次。虽然 python 可能没有本机只读常量,但我正在编写这部分代码以使用这些类似常量。wx.ID_ANY(与, 和wx.DEFAULT_FRAME类型的想法相同)

另一种说法是:是在第一次遇到(设置)变量时完成计算,然后是用于查找的指针,还是指向公式的指针,并且在每次遇到变量时计算公式?

注意:我需要基于 Python 2.7 的此信息,但对于 Python 3.X 的响应(如果不相同)也将不胜感激。如果您的回答仅适用于 2 或 3,请这样说。(我还没有深入研究 3,但计划好了,所以未来的使用知识也很好 ;-)

4

4 回答 4

2

除非您重置它们,否则它们只会被评估一次。如果你用评估来做数学,你会为数学付出一次代价,但在第一次阅读之后,它们会是相同的。

如果您真的希望每次都对它们进行评估,您可以用 lambdas 替换它们,但您必须用大括号调用它们:

pi = lambda : 3.14159265359
two_pi = lambda : 2 * pi()

around = two_pi() * r # note braces

FWIW Python 没有创建只读变量的本机方式,因此这里的“常量”是一个约定,而不是基本事实。

于 2013-01-02T03:45:38.993 回答
1

Python 在设置时计算变量的值,而变量只是一个指针。我会说第一个选项更清楚,因为运行时的唯一区别是 Python 需要多长时间才能将值转换为二进制存储 - 最小。

这是一般的Python,顺便说一句。

另外,您说您需要定义很多常量,那么为什么不使用 for 循环和 dict:

THIS_VAR = {}
for i in range(n):
    THIS_VAR[i] = 2 ** i

然后您可以通过 THIS_VAR[i] 访问这些值。它比手动定义每个常量要快得多。

于 2013-01-02T03:39:29.297 回答
1

Python 进行常量折叠。

>>> import dis
>>> def function():
...     return 2**21
... 
>>> dis.disassemble(function.__code__)
  2           0 LOAD_CONST               3 (2097152) 
              3 RETURN_VALUE         

2**21编译模块后,和之间将没有任何区别2097152

于 2013-01-02T04:44:45.670 回答
0

比使用运算符更有效**pow()可能使用<<运算符。然后您的代码可以替换为:

THIS_VAR_0 = 1<<0             # equal to 2**0; actually, it is 1
THIS_VAR_1 = 1<<1             # 2 
...
This_Var_N = 1<<N             # 2**N

Python 3的文档说:

左移 n 位相当于乘以 pow(2, n)而不进行溢出检查

对于Python 2.7,文档的同一部分说:

左移 n 位相当于乘以 pow(2, n)。如果结果超出普通整数的范围,则返回一个长整数。

...即它没有提到溢出检查。无论如何,它对两个版本的 Python 产生相同的结果。

移位运算符更自然地用于定义像 C 系列语言中的常量。对于处理器的本机整数,该操作非常快。无论如何,使用显式数字的情况也是很常见的,这应该是最有效的。(如果你真的timeit,请发布结果。)如果没有解释,它只会更不可读,更难理解。无论如何,您可以使用 shift 运算符添加注释:

THIS_VAR_0 = 0               # default
THIS_VAR_1 = 1               # 1 << 0
...
This_Var_N = 536870912       # 1 << 30

当心:您有问题中的错误。如果THIS_VAR_0应该为零,则不能生成为2**0

于 2013-01-02T23:04:47.923 回答