ftp.retrbinary() 使用帮助 Python
我写了一个Python脚本,用来连接到一个远程服务器。
datfile = []
for dk in range(len(files)):
dfnt=files[dk]
dpst=dfnt.find('.dat')
if dpst == 15:
dlist = dfnt[:]
datfile.append(dlist)
assert datfile == ['a.dat','b.dat']
# True
正如你所看到的,这段代码创建了一个列表。现在我把这个列表传递给
ftp.retrbinary('datfile')
但是这行代码返回了一个错误:
typeerror: retrbinary() takes at least 3 arguments (2 given)
我不太确定它在找什么?
1 个回答
33
这段话告诉你,你没有给retrbinary
这个方法提供足够的参数。
文档中说明,你还需要提供一个“回调”函数,这个函数会在每次收到数据块时被调用。你需要写一个回调函数,并对它给你的数据做点什么(比如写入文件、在内存中收集数据等)。
顺便提一下,可能你会问为什么需要“3”个参数,而不是“2”个。这是因为Python在实例方法中需要一个叫“self”的参数,但你是通过ftp
对象隐式地传递了这个参数。
编辑 - 看起来我可能没有完全回答你的问题。
对于command
参数,你应该传递一个有效的RETR命令,而不是一个列表。
filenames = ['a.dat', 'b.dat']
# Iterate through all the filenames and retrieve them one at a time
for filename in filenames:
ftp.retrbinary('RETR %s' % filename, callback)
对于callback
,你需要传递一个可以调用的东西(通常是某种函数),它接受一个参数。这个参数是从正在获取的文件中得到的一块数据。我说是一“块”,因为在移动大文件时,你通常不想把整个文件都放在内存里。这个库的设计是逐块调用你的回调函数,随着数据块的接收。这让你可以逐块写出文件,这样你在任何时候只需要在内存中保留相对较小的数据。
我这里的例子有点复杂,但你的回调可以是在打开的文件写入的for循环中的一个闭包:
import os
filenames = ['a.dat', 'b.dat']
# Iterate through all the filenames and retrieve them one at a time
for filename in filenames:
local_filename = os.path.join('/tmp', filename)
# Open a local file for writing (binary mode)...
# The 'with' statement ensures that the file will be closed
with open(local_filename, 'wb') as f:
# Define the callback as a closure so it can access the opened
# file in local scope
def callback(data):
f.write(data)
ftp.retrbinary('RETR %s' % filename, callback)
这也可以用lambda
语句更简洁地实现,但我发现新接触Python和一些函数式概念的人更容易理解第一个例子。不过,这里是用lambda的ftp调用:
ftp.retrbinary('RETR %s' % filename, lambda data: f.write(data))
我想你甚至可以这样做,直接把文件的write
实例方法作为你的回调传递:
ftp.retrbinary('RETR %s' % filename, f.write)
这三个例子应该是类似的,希望通过它们的追踪能帮助你理解发生了什么。
为了示例,我省略了任何错误处理。
另外,我没有测试上面的代码,所以如果它不工作,请告诉我,我会看看能否进一步解释。