ftp.retrbinary()帮助python

fab*_*aci 9 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
Run Code Online (Sandbox Code Playgroud)

如你所见,创建一个列表.现在我将此列表传递给

ftp.retrbinary('datfile')
Run Code Online (Sandbox Code Playgroud)

但是这一行会返回一个错误:

typeerror: retrbinary() takes at least 3 arguments (2 given)
Run Code Online (Sandbox Code Playgroud)

不知道在找什么?

Joe*_*way 27

它告诉你,你没有为该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)
Run Code Online (Sandbox Code Playgroud)

对于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)
Run Code Online (Sandbox Code Playgroud)

这也可以通过lambda语句更简洁地完成,但我发现Python新手,其中一些功能风格的概念更容易理解第一个例子.不过,这是使用lambda的ftp调用:

ftp.retrbinary('RETR %s' % filename, lambda data: f.write(data))
Run Code Online (Sandbox Code Playgroud)

我想你甚至可以这样做,write直接传递文件的实例方法作为你的回调:

ftp.retrbinary('RETR %s' % filename, f.write)
Run Code Online (Sandbox Code Playgroud)

所有这三个示例都应该是类似的,希望通过它们进行跟踪可以帮助您了解正在发生的事情.

为了举个例子,我已经省略了任何类型的错误处理.

此外,我没有测试任何上述代码,所以如果它不起作用,让我知道,我会看看我是否可以澄清它.

  • @ fabio.geraci-我扩大了答案,向您展示了更多有关`retrbinary`和`callback`的工作方式。我不知道比Python文档更好的文档,但是我同意该文档假定您具有一些Python的使用知识。如果这回答了您的问题,请确保将其标记为将来的旅行者接受。 (2认同)