Python 3.x Can';我不理解回调和带块的python变量范围

Python 3.x Can';我不理解回调和带块的python变量范围,python-3.x,Python 3.x,在编写从ftp服务器下载文件列表时显示进度条的函数时,我遇到了一些奇怪的脚本: ftplib.FTP(…)作为FTP的: 文件=列表(ftp.mlsd(路径=远程目录路径)) total_size=sum(文件中f的int(f[1]['size'])) 完成的总数=0 当前完成=0 当前大小=0 def回调(块): 全球电流单位完成 全球总完成量 全局当前大小 全球总面积 trg_file.write(chunk)#如何编写?为什么它知道什么是“trg_文件”? 当前_done+=len(块)

在编写从ftp服务器下载文件列表时显示进度条的函数时,我遇到了一些奇怪的脚本:

ftplib.FTP(…)作为FTP的
:
文件=列表(ftp.mlsd(路径=远程目录路径))
total_size=sum(文件中f的int(f[1]['size']))
完成的总数=0
当前完成=0
当前大小=0
def回调(块):
全球电流单位完成
全球总完成量
全局当前大小
全球总面积
trg_file.write(chunk)#如何编写?为什么它知道什么是“trg_文件”?
当前_done+=len(块)
总完成数+=len(块)
打印进度条(当前完成,总完成,…)
对于文件中的文件:
当前完成=0
当前大小=int(文件[1]['size'])
打开(文件[0],“wb”)作为训练文件:
ftp.retrbinary('RETR%s/%s'(远程目录路径,文件[0]),回调)
我必须在
callback
函数中编写
global
,这样python就不会抱怨了。但它知道什么是
trg_文件
没问题?!?!?! 为了理解,我写了一个小测试:

def callback():
打印(foo)
def main():
foo='fooo'
回调函数()
main()
果然失败了

我明白为什么第二个脚本不起作用。直觉告诉我们,第一种方法不应该起作用。但它是有效的。谁能解释一下原因吗? 编辑:
问题不在于
global
本身,而在于
与。。。as…
块和作用域(作用域为
…变量
变量)

执行以下操作时:

def abc():
    x = 5
x
变量是本地变量,同样适用于

def abc():
    x += 5
因为它基本上是
x=x+5
,所以再次分配运算符。 考虑这一点:

x = 1
def abc():
    print(x)
x = 1
def abc():
    print(x)
    x = 5
    print(x)

abc()
这里会发生什么<代码>x将被打印,因为x在abc功能范围内可用

现在考虑这个问题:

x = 1
def abc():
    print(x)
x = 1
def abc():
    print(x)
    x = 5
    print(x)

abc()
会发生什么?第一次打印会打印1吗?答案是,因为函数定义后面有
x=5
,因此
x
将被视为整个函数中的局部变量,包括第一个打印-它不会查看全局范围,因为局部范围中有一个
x
变量。第一次打印时还没有分配,这就是为什么会出现错误

现在,
with
语句不会创建范围。这就是为什么要为(全局)变量赋值时需要
global
关键字:
total\u size,total\u done,current\u done,current\u size

<> >为了解释为什么一些变量不需要<代码>全局< /代码>关键字,请考虑这个片段:

some_list = [1, 2, 3]
def abc():
    some_list = ['a', 'b', 'c']  # assignment to variable some_list, it is 
                                 # a local variable, it has nothing to do
                                 # with global some_list (it references a different object)
    print(some_list)

abc()
print(some_list)
>>> ['a', 'b', 'c']
>>> [1, 2, 3]

def cba():
    some_list.append(4)  # now there is no assignment so some_list is a global variable and references the same object in memory from the beginning

cba()
print(some_list)
>>> [1, 2, 3, 4]

如果它仍然让人困惑,有一个很好的网站,你可以在这里可视化哪些变量引用了内存中的哪个对象:。

这是否回答了你的问题?因此,
for
不会创建自己的范围->其“主体”中的赋值是全局的。和<代码>与。。。因为var不创建作用域,它类似于
var=…
,也是一个全局变量<代码>回调在使用。。。作为trg_文件,并在同一范围内。如果这是正确的,那么它是有意义的。非常感谢。不确定回调是什么意思:pI表示名为
callback
的函数。它与
try_file
定义在同一级别,在本例中,这两个文件都是全局的。因此,
callback
函数可以访问
tag\u文件
,因为它不在其“主体”中本地定义它。由于
回调
是在
标记文件
分配后调用的(借助于
with…
构造),因此
回调
具有读取权限!正确吗?=)无论如何,
与…
构造使它看起来像问题中的第二个脚本,您的解释有助于理解真正发生的事情!谢谢