Python: RecursionError: максимальная глубина рекурсии превышена при вызове объекта Python - PullRequest
0 голосов
/ 20 февраля 2020

Код, который я собирал, натолкнулся на эту ошибку сегодня, и я не могу понять, что не так и почему это происходит.

Ошибка:

Traceback (most recent call last):
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 63, in loop
    last_msg()
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 35, in last_msg
    loop()
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 63, in loop
    last_msg()
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 35, in last_msg
    loop()
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 61, in loop
    open_chatroom()
  File "D:/Drive/Outros/Python/Projects/Simple_Dict_bot.py", line 21, in open_chatroom
    WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CLASS_NAME, '_1ZMSM')))
  File "D:\py\lib\site-packages\selenium\webdriver\support\wait.py", line 71, in until
    value = method(self._driver)
  File "D:\py\lib\site-packages\selenium\webdriver\support\expected_conditions.py", line 64, in __call__
    return _find_element(driver, self.locator)
  File "D:\py\lib\site-packages\selenium\webdriver\support\expected_conditions.py", line 411, in _find_element
    return driver.find_element(*by)
  File "D:\py\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
    'value': value})['value']
  File "D:\py\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 319, in execute
    response = self.command_executor.execute(driver_command, params)
  File "D:\py\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 374, in execute
    return self._request(command_info[0], url, body=data)
  File "D:\py\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 397, in _request
    resp = self._conn.request(method, url, body=body, headers=headers)
  File "D:\py\lib\site-packages\urllib3\request.py", line 80, in request
    method, url, fields=fields, headers=headers, **urlopen_kw
  File "D:\py\lib\site-packages\urllib3\request.py", line 171, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
  File "D:\py\lib\site-packages\urllib3\poolmanager.py", line 330, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "D:\py\lib\site-packages\urllib3\connectionpool.py", line 672, in urlopen
    chunked=chunked,
  File "D:\py\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "D:\py\lib\site-packages\urllib3\connectionpool.py", line 416, in _make_request
    httplib_response = conn.getresponse()
  File "D:\py\lib\http\client.py", line 1321, in getresponse
    response.begin()
  File "D:\py\lib\http\client.py", line 320, in begin
    self.headers = self.msg = parse_headers(self.fp)
  File "D:\py\lib\http\client.py", line 214, in parse_headers
    return email.parser.Parser(_class=_class).parsestr(hstring)
  File "D:\py\lib\email\parser.py", line 68, in parsestr
    return self.parse(StringIO(text), headersonly=headersonly)
  File "D:\py\lib\email\parser.py", line 57, in parse
    feedparser.feed(data)
  File "D:\py\lib\email\feedparser.py", line 176, in feed
    self._call_parse()
  File "D:\py\lib\email\feedparser.py", line 180, in _call_parse
    self._parse()
  File "D:\py\lib\email\feedparser.py", line 295, in _parsegen
    if self._cur.get_content_maintype() == 'message':
  File "D:\py\lib\email\message.py", line 594, in get_content_maintype
    ctype = self.get_content_type()
  File "D:\py\lib\email\message.py", line 578, in get_content_type
    value = self.get('content-type', missing)
  File "D:\py\lib\email\message.py", line 471, in get
    return self.policy.header_fetch_parse(k, v)
  File "D:\py\lib\email\_policybase.py", line 316, in header_fetch_parse
    return self._sanitize_header(name, value)
  File "D:\py\lib\email\_policybase.py", line 287, in _sanitize_header
    if _has_surrogates(value):
  File "D:\py\lib\email\utils.py", line 57, in _has_surrogates
    s.encode()
RecursionError: maximum recursion depth exceeded while calling a Python object

Process finished with exit code 1

Это будет последней непрочитанное сообщение.

def w:
    try:
        post = driver.find_elements_by_class_name("_12pGw")
        ultimo = len(post) - 1
        texto = post[ultimo].find_element_by_css_selector(
            "span.selectable-text").text
        return texto
    except Exception:
        loop()

Создает словарь из pandas df и отвечает пользователю соответствующим ответом.

def y:
    df = pd.read_excel(r'D:\Drive\Outros\Python\Project\Dict.xlsx', error_bad_lines=False, encoding='utf-8-sig')
    d = df.set_index('msg')['reply'].to_dict()
    try:
        input_field = driver.find_element_by_class_name("_3u328")
        try:
            x = next(v for k, v in d.items() if last_msg() in k)
        except StopIteration:
            x = 'Não entendi, este comando é invalido'
        input_field.send_keys(x)
        time.sleep(1)
        driver.find_element_by_class_name("_3M-N-").click()
        try:
            driver.find_element_by_class_name("_2zCfw").send_keys('Lonely bot')
            driver.find_element_by_xpath("//span[@title = '{}']".format('Lonely bot')).click()
            driver.find_element_by_class_name("_2heX1").click()
            WebDriverWait(driver, 600).until(EC.invisibility_of_element_located((By.NAME, "status-time")))
        except TimeoutException:
            loop()
    except NoSuchElementException:
        loop()

Здесь я определил al oop, чтобы сохранить код онлайн

def loop:
    try:
        z()
        time.sleep(1)
        w()
        y()
        driver.refresh()
    except TimeoutException:
        loop()

Это первое чтение и ответ.

while True:
    try:
        open_chatroom()
        time.sleep(1)
        w()
        y()
        driver.refresh()
    except TimeoutException:
        loop()

Я никогда не испытывал этого раньше. Как я могу изменить свой код, чтобы мой l oop не ломался с этой ошибкой?

Ответы [ 2 ]

2 голосов
/ 20 февраля 2020

В вашем обработчике исключений ваша функция loop вызывает себя. Каждое TimeoutException исключение вы создаете новый кадр стека, и я думаю, что эти стековые кадры никогда не очищаются, что в итоге приводит к RecursionError.

1 голос
/ 21 февраля 2020

Глядя на последние несколько элементов в трассировке, кажется, что loop и last_msg многократно вызывают друг друга, поэтому существует рекурсия, которая включает две подпрограммы вместо одной самой вызывающей. Также возможен аналогичный цикл для функций loop и conversation.

. Цель состоит в том, чтобы чатбот продолжал работать в al oop все время, даже если вы нажали какую-то ошибку, но проблема возникает, когда loop вызывается снова в обработчиках исключений. Он запускает еще одну копию loop внутри last_msg, пока первая копия loop все еще работает. Так что last_msg вызывает loop, и это, в свою очередь, вызывает last_msg снова, и ни один из вызовов никогда не заканчивается sh, они просто накапливаются до тех пор, пока вы не выполните пробел.

Способ решения это просто return из функции, где вы перехватываете исключение, и замена функции loop на while True: l oop (точно так же, как последний блок кода в исходном вопросе).

Перехват исключений не позволяет им останавливаться, пока l oop. Если что-то не получается, тогда l oop будет пытаться снова и снова вечно, но тогда он будет делать это всегда внутри одного вызова функции, а не нового рекурсивного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...