ftp.retrbinary()帮助python

时间:2011-01-14 21:58:44

标签: python ftp binary ascii

我创建了一个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)

不确定要找什么?

1 个答案:

答案 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)

这三个例子都应该是类似的,希望通过它们进行追踪可以帮助你了解正在发生的事情。

为了示例,我省略了任何类型的错误处理。

另外,我没有测试上面的任何代码,所以如果它不起作用,请告诉我,我会看看是否可以澄清它。