我有以下功能定义(见下文)。
当我运行>>> pd = distrib(10,listAll)我得到这个(注意行号对应于我文件中不在下面示例中的行)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "transportOpt.py", line 78, in distrib
N = NN(0,t1)
File "transportOpt.py", line 48, in NN
print(p1,p2)
NameError: global name 'p1' is not defined
功能本身
def distrib(Nm,lf):
l = len(lf)
pd = {}# the output dictionary distribution
sumpd = 0# the total number of samples
p1=0
p2=0
buf=[lf[0]]
def NN(a,b):
global p1,p2
print(p1,p2)
y = max(a,b)
x = min(a,b)
if y>p2:
for j in range(p2-p1+1,y-p1+1):
buf.append(buf[j-1]+lf[j])
p2 = y
if x>p1:
for j in range(0,x-p1):
buf.pull(j)
p1 = x
return buf[b-p1]-buf[a-p1]
def UpdateDistrib(a,b):
global sumpd
tao = t1-t0
if tao < 0:
print('UpdateDistrib: t1<t0: mistake')
if tao == 0:
tao = 1
CurrentCount = pd.get(tao,0)
pd[tao] = CurrentCount + 1.
sumpd = sumpd + 1.
def normdistrib():
for i in pd.keys():
num = pd[i]
pd[i] = num/sumpd
for t1 in range(l):
N = NN(0,t1)
if N>Nm:
UpdateDistrib(0,t1)
break
if t1==l-1 and N<=Nm:
normdistrib()
return pd
for t0 in range(1,l):
N = NN(t0,t1)
if N<=Nm:
if t1==l-1:
normdistrib()
return pd
r = range(t1+1,l)
for t1 in r:
N = NN(t0,t1)
if N>Nm:
UpdateDistrib(t0,t1)
break
else:
UpdateDistrib(t0,t1)
normdistrib()
return pd
怎么了? 我是否以错误的方式使用“全球”?
答案 0 :(得分:3)
也许您认为global p1
使名称p1
引用在早期行上使用p1=0
定义的变量。它没有做到这一点,因为早期的变量不是全局的,它是函数distrib
的本地变量。
在定义嵌套函数时,您不需要global
来引用外部变量。但是,您无法(通过任何合理的方式)从Python 2.7中的嵌套函数分配外部变量。您需要nonlocal
,而且只能在Python 3.0+中使用p1
。您在嵌套函数中对p1
赋值的事实会阻止在外部函数中引用global
的名称,并使用{{1}}不会帮助。
答案 1 :(得分:1)
您是否在发布商之外定义了p1?这可能是你的问题,因为p1和p2仍然在distib函数中被使用,它们被“封闭”并且python将知道要操作哪些变量。完全摆脱全球化,它应该工作。 更多关于范围: Short Description of the Scoping Rules? 注意LEGB规则。本地,封闭,全球,内置
答案 2 :(得分:1)
你必须在函数&#39; distrib(Nm,lf)之外定义p1和p2:&#39;。全局函数用于更改原始函数之外的变量值,而不是将它们导入sub -def。
p1 = 0
p2 = 0
def distrib(Nm,lf):
l = len(lf)
pd = {}# the output dictionary distribution
sumpd = 0# the total number of samples
buf=[lf[0]]
def NN(a,b):
global p1,p2
print p1,p2