Python FTP在回调中挂起

时间:2013-08-05 22:23:16

标签: python callback ftplib

我正在使用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

即使在count电话中包裹str()也不起作用。它只是挂在第一个电话上。

2 个答案:

答案 0 :(得分:1)

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

>>> update('')
UnboundLocalError: local variable 'count' referenced before assignment

如果要更新全局变量,则必须明确地将其标记为全局:

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

有关更多详细信息,请参阅常见问题解答条目Why am I getting an UnboundLocalError when the variable has a value?和以下问题What are the rules for local and global variables in Python?以及global上的文档。


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

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)

答案 1 :(得分:1)

它不只是挂起,而是产生异常(特别是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.