2011-01-14 15 views
9

He creado un script de python para conectarme a un servidor de rems.ftp.retrbinary() help 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 

que como puede ver crea una lista. Ahora estoy pasando esta lista para

ftp.retrbinary('datfile') 

pero estas líneas devuelve un error:

typeerror: retrbinary() takes at least 3 arguments (2 given) 
no

seguro de lo que está buscando?

+3

Por favor, vuelva a formatear su pregunta de una manera que preserve la sangría del código de Python y la separación general del texto del código. – ulidtko

Respuesta

22

Le indica que no está suministrando suficientes argumentos para el método retrbinary.

documentation specifies que también debe proporcionar una función de "devolución de llamada" que recibe llamadas para cada bloque de datos recibidos. Deberá escribir una función de devolución de llamada y hacer algo con los datos que le proporciona (por ejemplo, escribir en un archivo, recopilarlo en la memoria, etc.)

Como nota al margen, puede preguntar por qué dice allí son '3' argumentos requeridos en lugar de solo '2'. Esto se debe a que también está contando el argumento "propio" que Python requiere en los métodos de instancia, pero está implícitamente pasando eso con la referencia de objeto ftp.

EDIT - Parece que no he respondido completamente su pregunta.

Para el argumento command se supone que debe pasar un comando RETR válido, no una lista.

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) 

Para el callback, tiene que pasar algo que es exigible (por lo general una función de algún tipo) que acepta un solo argumento. El argumento es un fragmento de datos del archivo que se está recuperando. Digo un "fragmento" porque cuando mueve archivos grandes, rara vez desea mantener todo el archivo en la memoria. La biblioteca está diseñada para invocar su devolución de llamada de forma iterativa a medida que recibe fragmentos de datos. Esto le permite escribir fragmentos del archivo para que solo tenga que mantener una cantidad relativamente pequeña de datos en la memoria en un momento dado.

Mi ejemplo aquí es un poco avanzado, pero su devolución de llamada puede ser un cierre dentro del bucle que se escribe en un archivo que se ha abierto:

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) 

Esto también se puede hacer de manera más concisa con un lambda declaración, pero encuentro gente nueva en Python y algunos de sus conceptos de estilo funcional entienden el primer ejemplo más fácilmente. Sin embargo, aquí está la llamada ftp con una lambda en su lugar:

ftp.retrbinary('RETR %s' % filename, lambda data: f.write(data)) 

supongo que se podría incluso hacer esto, pasando el método write instancia del archivo directamente como su devolución de llamada:

ftp.retrbinary('RETR %s' % filename, f.write) 

Estos tres los ejemplos deben ser análogos y, con suerte, rastrearlos lo ayudará a comprender lo que está sucediendo.

Me he olvidado de cualquier tipo de manejo de errores por ejemplo.

Además, no probé ninguno de los códigos anteriores, por lo tanto, si no funciona, házmelo saber y veré si puedo aclararlo.

+0

gracias, no entendía que tenía que proporcionar una función de devolución de llamada, ¿podría indicarme algunos buenos documentos, he intentado buscar algo de información pero todavía estoy un poco confundido? en cuanto a la lista que estoy tratando de pasar a la retrbinary, ¿es aceptable? –

+1

@ fabio.geraci - He ampliado mi respuesta para mostrarle más sobre cómo funciona 'retrbinary' y' callback'. No conozco ninguna documentación mejor que los documentos de Python, pero estoy de acuerdo en que la documentación supone que usted tiene algún conocimiento práctico de Python. Si esto responde sus preguntas, asegúrese de marcarlo aceptado para futuros viajeros. –

+0

Muchas gracias –