我疯了。这个简单的回调函数无法识别在它的父作用域之前分配的变量。我收到local variable 'elapsed' referenced before assignment
错误。为什么呢?
total = os.path.getsize(filename)
elapsed = 0
def progress_print(chunk):
elapsed += len(chunk) # elapsed is apparently unassigned??
percent = float(elapsed) / float(total) * 100
print ' Copied %s%%\033[A' % int(percent)
ftp.upload(filename, temp_path, callback=progress_print)
答案 0 :(得分:4)
您正在尝试分配给全球。 Python让你明确地做到这一点。
def progress_print(chunk):
global elapsed
elapsed += len(chunk)
一般来说,这是一个非常好的迹象,表示您需要重构代码,直到您不再需要全局变量。
请注意,赋值和访问是不同的野兽 - 前者要求您显式声明全局变量,后者则不需要。举个例子,你的total
变量是另一个全局变量,但你不会尝试赋值给它,因此python不会抱怨。
Programming FAQ详细介绍:
Python中的局部变量和全局变量有哪些规则?
在Python中,仅在函数内引用的变量是 隐含全球性。如果在任何地方为变量分配了新值 在函数体内,它被认为是一个本地的。如果是变量 在函数内部分配了一个新值,变量是 隐式本地,您需要明确地将其声明为“全局”。
虽然起初有点令人惊讶,但片刻的考虑解释了 这个。一方面,要求全局分配变量提供了一个 禁止意外的副作用。另一方面,如果全球化了 所有全局引用都需要,你将全局使用全局 时间。您必须将每个对内置的引用声明为全局 功能或导入模块的组件。这种混乱会 打败全球宣言的有用性 副作用。
答案 1 :(得分:0)
当你做
时def progress_print(chunk):
elapsed += len(chunk)
这里过去的是新的局部变量。因为你正在做+ =,这只不过是:
elapsed = elapsed + len(chunk)
这里,elapsed没有用任何值初始化,这就是你得到错误的原因 - 在赋值之前引用了。
因此你需要这样做:
def progress_print(chunk):
global elapsed
elapsed += len(chunk)