2016-04-24 100 views
-3

我遇到了一些麻烦在Python 3 ftplib模块,一些调试后,我发现了错误:在FTP类的getline()方法返回b'somestring'(但作为一个字符串,而不是字节),而不是的somestring。我可以.decode("utf-8")解决这个问题,用的Python:在标准库覆盖方法

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

解决了错误替换所述第一线中的函数

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

。但现在,我不想手动编辑文件ftplib.py,而是想在我的代码中覆盖它。但是,当我使用FTP_TLS类,它继承FTP,我不出来,怎么办?

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

在我的代码不能正常工作的开始,因为没有按FTP_TLS”不承认我对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

我觉得**最小**需要加强,问题描述仍然没有告诉我们任何有用的东西。 – 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

我试图将它包含在我的代码开始处,并未修复错误。 – linusg