2011-01-14 13 views
9

Ho creato uno script python per connettersi a un server di 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 

che come è possibile vedere creare un elenco. ora sto passando questo elenco per

ftp.retrbinary('datfile') 

ma questo le linee restituisce un errore:

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

sicuro di quello che sta cercando?

+3

Si prega di riformattare la domanda in modo da preservare il rientro del codice Python e la separazione complessiva del testo dal codice. – ulidtko

risposta

22

Si sta dicendo che non si forniscono argomenti sufficienti al metodo retrbinary.

Il documentation specifies che è necessario anche fornire una funzione di "richiamata" che viene chiamata per ogni blocco di dati ricevuti. Avrai voglia di scrivere una funzione di callback e fare qualcosa con i dati che ti danno (es. Scriverlo in un file, raccoglierlo in memoria, ecc.)

Come nota a margine, potresti chiedere perché ci dice sono gli argomenti obbligatori '3' invece di solo '2'. Questo perché sta anche contando l'argomento 'self' richiesto da Python sui metodi di istanza, ma lo si sta passando implicitamente con il riferimento all'oggetto ftp.

EDIT - Sembra che forse non ho risposto interamente alla tua domanda.

Per l'argomento command si suppone che si stia passando un comando RETR valido, non un elenco.

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) 

Per il callback, è necessario passare qualcosa che è richiamabile (di solito una funzione di qualche tipo) che accetta un singolo argomento. L'argomento è una porzione di dati dal file che si sta recuperando. Dico un "chunk" perché quando si spostano file di grandi dimensioni, raramente si desidera conservare l'intero file in memoria. La libreria è progettata per richiamare la tua callback in modo iterativo quando riceve blocchi di dati. Ciò consente di scrivere blocchi del file in modo che sia necessario conservare una quantità relativamente piccola di dati in memoria in qualsiasi momento.

Il mio esempio qui è un po 'avanzato, ma il callback può essere una chiusura all'interno del ciclo for che scrive su un file che è stato aperto:

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) 

Questo può anche essere fatto in modo più conciso con un lambda dichiarazione, ma trovo le persone nuove in Python e alcuni dei suoi concetti in stile funzionale comprendono più facilmente il primo esempio. Tuttavia, ecco la chiamata ftp con un lambda invece:

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

Suppongo che si potrebbe anche fare questo, passando il metodo del file write esempio direttamente come il callback:

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

Tutti e tre questi gli esempi dovrebbero essere analoghi e, si spera, tracciarli attraverso ti aiuterà a capire cosa sta succedendo.

Ho eluso qualsiasi tipo di gestione degli errori per motivi di esempio.

Inoltre, non ho provato nessuno dei codici precedenti, quindi se non funziona fammelo sapere e vedrò se posso chiarirlo.

+0

grazie, non ho capito che dovevo fornire una funzione di callback, saresti in grado di indicarmi alcuni buoni documenti, ho cercato di cercare alcune informazioni ma ancora un po 'di confusione. per quanto riguarda la lista che sto cercando di passare al retrbinary, è accettabile? –

+1

@ fabio.geraci - Ho ampliato la mia risposta per mostrarvi di più su come funzionano 'retrbinary' e' callback'. Non conosco documentazione migliore dei documenti Python, ma sono d'accordo che la documentazione presuppone che tu abbia una conoscenza pratica di Python. Se questo risponde alle tue domande, assicurati di contrassegnarlo come accettato per i futuri viaggiatori. –

+0

Grazie mille –