在全局声明之前使用的Python 3 SyntaxWarning变量

在全局声明之前使用的Python 3 SyntaxWarning变量,python,python-3.x,syntax-error,Python,Python 3.x,Syntax Error,我得到以下错误: 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

我得到以下错误:

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开始,这是一个错误。因此,您最好现在修复它,否则它将无法在将来的版本中执行(
=3.6

请参阅以下页面上的文档:

global
语句中列出的名称不得在该全局语句前面的同一代码块中使用

正如您所注意到的,这不是在运行时生成的警告,而是在Python编译函数对象并注意到包含名称(
primeRan
)的
global
语句时生成的,该名称已被发现为本地名称

在这里引用
primeRan
之前,您应该添加
global
语句,并对同一问题的受害者
primerist
执行相同的操作

不过,对于
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
不是一个好的做法。老实说,我看不出有什么理由需要使用它们,你最好(从概念和执行速度的角度来看)放弃使用
全局变量
,而是使用参数和返回值与函数通信。

由于变量是不可变的,所以可能会重复,您需要添加
global
,否则python将创建另一个本地引用(如果指定),并且在逻辑上,在访问它时查找本地引用。@Jean-Françoisfare我的问题不是天气或是否需要全局减速。虽然我很高兴你能引起我的注意,因为它提供了信息。我提供的示例是一段复杂的代码,后来我通过包括删除外部引用在内的简化改进了它(相对于计算时间)。我的问题是关于警告本身。答案比我想象的更贴切。我不知道将来的版本会停止执行代码。我发现吉姆的回答很有启发性。Jean-Françoisfare,作为旁注,外部列表将被更改,不管它们是否被声明为全局,程序无法按预期运行(限制对生成器第一个实例的外部写入)。这就是我从另一篇文章中得到的启示,它回答了一个不同的问题。我在Python3.6上尝试了它,正如你所说的。你改变if语句顺序的想法也行得通。