2011-01-14 21 views
9

Tôi đã tạo một tập lệnh python để kết nối với máy chủ lưu trữ.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 

mà bạn có thể thấy tạo danh sách. bây giờ tôi đang đi qua danh sách này để

ftp.retrbinary('datfile') 

nhưng dòng này trả về một lỗi:

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

không chắc chắn những gì đang tìm kiếm?

+3

Vui lòng định dạng lại câu hỏi của bạn theo cách duy trì thụt đầu dòng mã Python và tách toàn bộ văn bản khỏi mã. – ulidtko

Trả lời

22

Điều này cho bạn biết rằng bạn không cung cấp đủ đối số cho phương thức retrbinary.

documentation specifies rằng bạn cũng phải cung cấp chức năng 'gọi lại' được gọi cho mọi khối dữ liệu nhận được. Bạn sẽ muốn viết một chức năng gọi lại và làm một cái gì đó với dữ liệu nó cung cấp cho bạn (ví dụ như ghi nó vào một tập tin, thu thập nó trong bộ nhớ, vv)

Như một lưu ý, bạn có thể hỏi tại sao nó nói ở đó là đối số bắt buộc '3' thay vì chỉ '2'. Điều này là bởi vì nó cũng đếm đối số 'tự' mà Python yêu cầu trên các phương thức ví dụ, nhưng bạn đang ngầm truyền nó với tham chiếu đối tượng ftp.

EDIT - Có vẻ như tôi có thể không trả lời hoàn toàn câu hỏi của bạn.

Đối với đối số command bạn có nghĩa vụ phải chuyển một lệnh RETR hợp lệ, không phải danh sách.

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) 

Đối với callback, bạn cần phải vượt qua một cái gì đó có thể được gọi (thường là một chức năng của một số loại) mà chấp nhận một đối số duy nhất. Đối số là một đoạn dữ liệu từ tệp đang được truy lục. Tôi nói 'chunk' vì khi bạn di chuyển các tệp lớn xung quanh, bạn hiếm khi muốn giữ toàn bộ tệp trong bộ nhớ. Thư viện được thiết kế để gọi lặp lại của bạn khi nó nhận được khối dữ liệu. Điều này cho phép bạn viết ra các phần của tệp để bạn chỉ phải giữ một lượng dữ liệu tương đối nhỏ trong bộ nhớ tại bất kỳ thời điểm nào.

dụ của tôi ở đây là một chút tiên tiến, nhưng gọi lại của bạn có thể là một đóng cửa bên trong vòng lặp for mà viết vào một tập tin mà đã được mở:

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) 

này cũng có thể được thực hiện chính xác hơn với một lambda tuyên bố, nhưng tôi tìm thấy những người mới với Python và một số khái niệm kiểu chức năng của nó hiểu ví dụ đầu tiên dễ dàng hơn. Tuy nhiên, đây là cuộc gọi ftp với một lambda thay vì:

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

Tôi cho rằng bạn thậm chí có thể làm được điều này, đi qua các phương pháp write thể hiện của các tập tin trực tiếp như gọi lại của bạn:

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

Cả ba các ví dụ nên tương tự và hy vọng truy tìm qua chúng sẽ giúp bạn hiểu những gì đang xảy ra.

Tôi đã loại trừ bất kỳ loại xử lý lỗi nào vì mục đích ví dụ.

Ngoài ra, tôi đã không kiểm tra bất kỳ mã nào ở trên, vì vậy nếu nó không hoạt động, hãy cho tôi biết và tôi sẽ xem liệu tôi có thể làm rõ nó hay không.

+0

cảm ơn, tôi không hiểu rằng tôi đã phải cung cấp một chức năng gọi lại, bạn sẽ có thể chỉ cho tôi một số tài liệu tốt, tôi đã cố gắng tìm một số thông tin nhưng vẫn còn một chút nhầm lẫn. theo như danh sách mà tôi đang cố gắng chuyển đến mục hồi quy, điều đó có được chấp nhận không? –

+1

@ fabio.geraci - Tôi đã mở rộng câu trả lời của mình để cho bạn biết thêm về cách 'retrbinary' và' callback' hoạt động. Tôi không biết bất kỳ tài liệu nào tốt hơn tài liệu Python, nhưng tôi đồng ý tài liệu giả định rằng bạn có một số kiến ​​thức làm việc về Python. Nếu điều này trả lời câu hỏi của bạn, hãy đảm bảo đánh dấu câu hỏi đó cho những khách du lịch trong tương lai. –

+0

Cảm ơn bạn rất nhiều –

Các vấn đề liên quan