2016-04-24 42 views
-3

私は、Python 3でftplibモジュールといくつかのトラブルがあったが、いくつかのデバッグの後、私は間違いを見つけた:FTPクラスのgetline()方法はb'somestring'を返します(ただし、文字列ではなく、バイトとして)の代わりにsomestring。私はPythonの標準ライブラリでオーバーライドメソッド

line = self.file.readline(self.maxline + 1).decode("utf-8") 

がエラーを解決して機能

line = self.file.readline(self.maxline + 1) 

の最初の行を置き換える、.decode("utf-8")でこれを解決することができます。しかし今、ファイルftplib.pyを手作業で編集しないで、自分のコードで上書きしたいと思っています。しかし、私のコード内の先頭に

class FTP: 
    def getline(self): 
     line = self.file.readline(self.maxline + 1).decode("utf-8") 
     ... 

...私は FTPから継承 FTP_TLSクラスを使用しています、私が行う方法、それを把握することはできませんがが動作しない、 FTP_TLSは「doesnのため私が FTPに行った変更を認識しません。

サンプル:

import ftplib 
import socket 
import ssl 


class FTP(ftplib.FTP): 
    def getline(self): 
     line = self.file.readline(self.maxline + 1).decode("utf-8") 
     if len(line) > self.maxline: 
      raise ftplib.Error("got more than %d bytes" % self.maxline) 
     if self.debugging > 1: 
      print('*get*', self.sanitize(line)) 
     if not line: 
      raise EOFError 
     if line[-2:] == ftplib.CRLF: 
      line = line[:-2] 
     elif line[-1:] in ftplib.CRLF: 
      line = line[:-1] 
     return line 


class FTPS(ftplib.FTP_TLS): 
    def __init__(self, host='', user='', passwd='', acct='', keyfile=None, certfile=None, timeout=60): 
     ftplib.FTP_TLS.__init__(self, host=host, user=user, passwd=passwd, acct=acct, keyfile=keyfile, 
           certfile=certfile, timeout=timeout) 

    def connect(self, host='', port=0, timeout=-999, source_address=None): 
     if host != '': 
      self.host = host 
     if port > 0: 
      self.port = port 
     if timeout != -999: 
      self.timeout = timeout 
     try: 
      self.sock = socket.create_connection((self.host, self.port), self.timeout) 
      self.af = self.sock.family 
      self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, ssl_version=ssl.PROTOCOL_TLSv1_2) 
      self.file = self.sock.makefile('rb') 
      self.welcome = self.getresp() 
     except Exception as e: 
      print(e) 
     return self.welcome 

if __name__ == "__main__": 
    ftps = FTPS() 
    ftps.connect("host", 990) # Returns b'welcomemessage' 
    ftps.login("user", "pwd") 
    ftps.prot_p() 

    ftps.close() 
+1

あなたはもらえあなたの現在のコードの[mcve]と、「*うまくいかない」*よりも優れた問題の記述*? – jonrsharpe

+0

@jonrsharpe投稿を更新しました。自分のコードを見ていただければ幸いです! – linusg

+1

私は** minimal **が強化を必要としているように感じています。問題の説明はまだ役に立たないとは言いません。 – jonrsharpe

答えて

2

はまず、それがバイトストリームのエンコーディングを想定していないことにより、正しいことをしftplibの欠陥、ではありません。私の後に繰り返し:ファイルやソケットのバイトは、デコードするまでは文字列ではありません!さらに読書:

http://www.joelonsoftware.com/articles/Unicode.html

は、あなたがまだエンコーディングを想定しftplibをモンキーパッチしたい場合は、と言ったが、常にUTF-8である、あなたは、潜在的に、このようにそれを行うことができます:

from ftplib import FTP 

origGetLine = FTP.getline 
def assumeUtf8GetLine(*args, **kwargs): 
    return origGetLine(*args, **kwargs).decode('utf-8') 
FTP.getline = assumeUtf8GetLine 
+0

ありがとうございますが、私のためには動作しません – linusg

+3

@linusg * "うまくいかない" *非常に役に立たないエラー報告 – jonrsharpe

+0

私のコードのbeginnignにインクルードしようとしましたが、エラーを修正しません。 – linusg

関連する問題