我创建了一个python脚本来连接到remserver。
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)
不确定要找什么?
答案 0 :(得分:26)
它告诉您,您没有为retrbinary
方法提供足够的参数。
documentation specifies您还必须提供一个'回调'函数,该函数将针对收到的每个数据块进行调用。你会想要编写一个回调函数,并对它给你的数据做一些事情(例如将其写入文件,在内存中收集等)。
作为旁注,你可能会问为什么它说'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)
这三个例子都应该是类似的,希望通过它们进行追踪可以帮助你了解正在发生的事情。
为了示例,我省略了任何类型的错误处理。
另外,我没有测试上面的任何代码,所以如果它不起作用,请告诉我,我会看看是否可以澄清它。