Python中ftp.retrbinary()函数的帮助

11

我已经创建了一个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方法中没有提供足够的参数。

文档指明,你还必须提供一个'callback'函数,用于在接收到每个数据块时进行调用。你需要编写一个回调函数并对其给出的数据执行某些操作 (例如将其写入文件、在内存中收集等)。

作为附注,你可能会问为什么它说有 '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)

这三个例子应该是类似的,希望通过对它们的追踪能帮助你理解正在发生什么。

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

此外,我没有测试上述代码,如果它不起作用,请告诉我,我会尽力澄清。


谢谢,我没理解到我需要提供一个回调函数,您能指向一些好的文档吗?我一直在尝试寻找一些信息但仍然有点困惑。至于我正在尝试传递给retrbinary的列表,这是可以接受的吗? - fabio.geraci
2
@fabio.geraci - 我已经扩展了我的答案,向您展示了更多关于retrbinarycallback如何工作的内容。我不知道有比Python文档更好的文档,但我同意文档假定您具有一些Python的工作知识。如果这回答了您的问题,请确保将其标记为已接受,以供未来的旅行者参考。 - Joe Holloway
有没有其他的回调函数示例,我们可以用来复制文件而不是打开和写入? - Shyam Sunder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接