Python FTP挂起在回调中

Python FTP挂起在回调中,python,callback,ftplib,Python,Callback,Ftplib,我正在使用ftplib创建一个简单的脚本,将文件推送到多个IP地址,所有这些都设置为FTP服务器。我想显示文件上传过程中的进度,但我遇到了一个问题。我使用了FTP.storbinary()的回调参数,它的工作原理如下: count = 0 def update(block): count2 = str(count + 1) print count2 但是,如果我尝试在str()调用之外执行任何算术运算,程序将挂起。因此,以下方法不起作用: count = 0 def update(

我正在使用
ftplib
创建一个简单的脚本,将文件推送到多个IP地址,所有这些都设置为FTP服务器。我想显示文件上传过程中的进度,但我遇到了一个问题。我使用了
FTP.storbinary()
的回调参数,它的工作原理如下:

count = 0
def update(block):
   count2 = str(count + 1)
   print count2
但是,如果我尝试在
str()
调用之外执行任何算术运算,程序将挂起。因此,以下方法不起作用:

count = 0
def update(block):
   count += 1
   print count

即使在
str()
调用中包装
count
也不起作用。它在第一次调用时挂起。

如果您自己尝试调用
update
,而不是将其传递到
FTP.storbinary
,您会立即看到问题:

>>> update('')
UnboundLocalError: local variable 'count' referenced before assignment
如果要更新全局变量,必须显式将其标记为全局变量:

def update(block):
   global count
   count += 1
   print count
有关更多详细信息,请参阅常见问题解答条目和以下问题以及上的文档


解决此问题的更好方法是编写一个类:

class FtpHandler(object):
    def __init__(self):
        self.count = 0
    def update(self, block):
        self.count += 1
        print self.count
然后,要使用它,您需要构造一个类的实例,并将绑定方法而不是普通函数传递给FTP代码。例如,与此相反:

ftp = ftplib.FTP(...)
# ...
ftp.storbinary(spam, eggs, callback=update)
…这样做:

myhandler = FtpHandler()
ftp = ftplib.FTP(...)
# ...
ftp.storbinary(spam, eggs, callback=myhandler.update)

它不仅会挂起,还会产生异常(特别是
UnboundLocalError
)。您试图修改函数内部的全局变量;要执行此操作,必须将变量声明为
global

count = 0
def update(block):
   global count
   count += 1
   print count
这几乎总是一个糟糕设计的标志,在您的情况下,最好使用带有属性的类:

class MyCallbackHandler(object):
    def __init__(self):
        self.count = 0

    def update(self, block):
        self.count += 1
        #... etc.

哦,是的。我完全忘记了。我已经有一段时间没有使用python了。我同意这个类会更好,但它只是一个简单的一次性工具,所以我不担心它。我只是想弄清楚到底发生了什么。