我收到以下错误:
Warning (from warnings module):
File "C:\Python34\projectEuler\projectEuler.py", line 316
global primeSet, primeList, primeCap, primeRan
SyntaxWarning: name 'primeRan' is used prior to global declaration
对于代码:
primeSet = {2, 3}
primeList = [2, 3]
primeCap = 3
primeRan = False
def primeGen():
if primeRan:
primeList, primeCap = primeList, PrimeCap
global primeSet
else:
global primeSet, primeList, primeCap, primeRan
primeRan = True
for i in primeList:
yield i
while(True):
primeCap += 2
m = int(primeCap**.5)
yesPrime = True
for p in primeList:
if p > m: break
if primeCap%p == 0:
yesPrime = False
break
if yesPrime:
primeSet.add(primeCap)
primeList.append(primeCap)
yield primeCap
变量在赋值之前不会被写入。而且代码似乎有效。 语法消息是误报,还是应该在读取之前声明全局? (而不是只在写入前声明)
代码:
def primeGen():
global primeRan
if primeRan:
primeList, primeMax = primeList, PrimeCap
global primeSet
else:
global primeSet, primeList, primeCap
primeRan = True
摆脱 SyntaxWarning
。但是对于一个只读不写的值进行全局减速似乎是错误的。
我应该忽略语法警报吗?
最佳答案
不,你不能忽略它,从 Python 3.6
开始,这个 will cease to be a SyntaxWarning
and instead be updated to an error (SyntaxError
) .所以你最好现在就修复它,或者面对它在未来版本 (>= 3.6
) 中不执行的前景。
请参阅 global
statement 上的文档:
Names listed in a
global
statement must not be used in the same code block textually preceding that global statement.
正如您所注意到的,这不是在运行时生成的警告,它是在 Python 编译您的函数对象并注意到包含名称的 global
语句时生成的(primeRan
) 已经被发现是本地的。
您应该在此处引用 primeRan
之前添加 global
语句并且对 primeList
执行相同的操作同一问题的受害者。
但是,对于 primeList
,您可以偷偷摸摸地利用 global
必须 首先被解析的事实。简而言之,切换条件,以便 Python 在 赋值语句之前为它解析 global
语句:
def primeGen():
global primeRan
if not primeRan:
global primeSet, primeList, primeCap
primeRan = True
else:
primeList, primeMax = primeList, PrimeCap
# rest as is
因为 global
是解析器的一个指令,这会产生相同的行为而没有警告。
当然,使用globals
并不是一个好习惯。老实说,我看不出你需要使用它们的任何理由,你总是更好(从概念的角度和执行速度的角度来看)放弃 globals
的使用而是使用参数和返回值与您的函数通信。
关于在全局声明之前使用的 Python 3 SyntaxWarning 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41432765/