len和str.splitlines()的奇怪行为

时间:2015-05-25 17:48:41

标签: python string typeerror python-3.4

我正在使用requests库发出HTTP请求,我想创建一个简单的响应对象来解析我的数据。我遇到的问题如下。将响应对象传递给我的ApiResponse时,我将Response.text分成行,计算它们并知道它是否有多行或单行。问题是splitlines列表在将len()应用于此时给出了错误,但在控制台中它可以正常工作。

这是班级:

class ApiResponse(object):
pattern = re.compile(r'([a-zA-Z]+): ([a-zA-Z0-9]+)')  # original ([a-zA-Z]+)\: ([a-zA-Z0-9]+)
response_type = ResponseType.OK
response_mode = ResponseMode.SINGLE

def __init__(self, r: resp):
    self.r = r
    self.parse(r)
    self.data = None

def parse(self, r: resp):
    """
    Method that parses the response from the API
    :param r:Response
    """
    if r.status_code != 200:
        self.response_type = ResponseType.ERR

    if len(r.text.splitlines()) > 1:
        self.response_mode = ResponseMode.MULTI

    for line in r.text.splitlines():
        match = self.pattern.search(line)
        if match is None:
            break
        print(match.group(1, 2))  # REMOVE testing
        self.response_type = ResponseType[match.group(1)]

这是控制台输出:

>>> import sys
>>> print(sys.version)
3.4.2 (default, Oct  8 2014, 13:08:17) 
[GCC 4.9.1]
>>> import requests
>>> from clickapy.response import ApiResponse
>>> r = requests.get(API_URL, {'user': USER, 'password': PASS, 'api_id': API_ID})
>>> api_response = ApiResponse(r)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/home/eefret/PycharmProjects/clickapy/clickapy/response.py", line 32, in __init__
    self.parse(r)
  File "/home/eefret/PycharmProjects/clickapy/clickapy/response.py", line 43, in parse
    if len(r.text.splitlines()) > 1:
TypeError: object of type 'builtin_function_or_method' has no len()
>>> len(r.text.splitlines())
1

为什么会这样?它对我来说没有意义,我执行相同的代码,欢迎任何帮助或反馈。

1 个答案:

答案 0 :(得分:1)

我的一位朋友( Mariano Garcia 的所有积分)帮助了我,因为他没有SO账号我将发布解决此问题的内容,我的控制台正在执行utf-8但在内部仍然必须对文字进行编码以解决此问题,将此if len(r.text.splitlines()) > 1:更改为此if len(r.text.encode("utf-8").splitlines()) > 1:

完整的代码:

class ApiResponse(object):
    pattern = re.compile(r'([a-zA-Z]+): ([a-zA-Z0-9]+)')  # original ([a-zA-Z]+)\: ([a-zA-Z0-9]+)
    response_type = ResponseType.OK
    response_mode = ResponseMode.SINGLE

    def __init__(self, r: resp):
        self.r = r
        self.parse(r)
        self.data = None

    def parse(self, r: resp):
        """
        Method that parses the response from the API
        :param r:Response
        """
        if r.status_code != 200:
            self.response_type = ResponseType.ERR

        if len(r.text.encode("utf-8").splitlines()) > 1:
            self.response_mode = ResponseMode.MULTI

        for line in r.text.splitlines():
            match = self.pattern.search(line)
            if match is None:
                break
            print(match.group(1, 2))  # REMOVE testing
            self.response_type = ResponseType[match.group(1)]