Это говорит о том, что вы не предоставляете достаточное количество аргументов для метода retrbinary
.
В документации указано , что вы также должны предоставить функцию обратного вызова, которая вызывается для каждого полученного блока данных. Вы захотите написать функцию обратного вызова и сделать что-то с данными, которые она вам дает (например, записать это в файл, собрать в памяти и т. Д.)
В качестве примечания вы можете спросить, почему в нем говорится, что для аргументов требуется «3», а не «2». Это потому, что он также считает аргумент 'self', который требуется Python для методов экземпляра, но вы неявно передаете его с помощью 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, и некоторые из его концепций функционального стиля легче понимают первый пример. Тем не менее, вот вместо этого вызов ftp с лямбдой:
ftp.retrbinary('RETR %s' % filename, lambda data: f.write(data))
Полагаю, вы могли бы даже сделать это, передав метод экземпляра write
файла непосредственно в качестве обратного вызова:
ftp.retrbinary('RETR %s' % filename, f.write)
Все три из этих примеров должны быть аналогичными, и, надеюсь, их прохождение поможет вам понять, что происходит.
Я исключил любую обработку ошибок для примера.
Кроме того, я не тестировал ни один из приведенных выше кодов, поэтому, если он не работает, дайте мне знать, и я посмотрю, смогу ли я уточнить это.