Ошибка Traceback (most recent call last): (Python)

написал код который генерирует рандомные пароли вот собственно сам код:

import random
from random import choice
from string import ascii_uppercase




        
def test():
    cs = random.randint(8,25)
    symbols = 'abcdefghijklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_'
    rand = (''.join(choice(symbols) for i in range(cs)))
    if rand == "testPIN12345":
        print (rand)

    else:
        test()

test()

по идеи он должен работать до тех пор пока не сгенерирует рандомный пароль совпадающий со значением в if rand == "testPIN12345": но вылетает ошибка:

Traceback (most recent call last):
  File "C:\test\test.py", line 19, in <module>
    test()
  File "C:\test\test.py", line 17, in test
    test()
  File "C:\test\test.py", line 17, in test
    test()
  File "C:\test\test.py", line 17, in test
    test()
  [Previous line repeated 1017 more times]
  File "C:\test\test.py", line 12, in test
    rand = (''.join(choice(symbols) for i in range(cs)))
  File "C:\test\test.py", line 12, in <genexpr>
    rand = (''.join(choice(symbols) for i in range(cs)))
  File "C:\Users\epicb\AppData\Local\Programs\Python\Python38\lib\random.py", line 288, in choice
    i = self._randbelow(len(seq))
  File "C:\Users\epicb\AppData\Local\Programs\Python\Python38\lib\random.py", line 254, in _randbelow_with_getrandbits
    k = n.bit_length()  # don't use (n-1) here because n can be 1
RecursionError: maximum recursion depth exceeded while calling a Python object

Ответы (2 шт):

Автор решения: nomnoms12

Вы превысили лимит рекурсии (вызова функции test из самой себя). Посмотреть его можно так:

import sys
print(sys.getrecursionlimit())  # 1000

Данный лимит нужен, чтобы не переполнить стек, так как Python не оптимизирует хвостовую рекурсию.

Вам следует переписать этот код динамически:

def test():
    is_first = True
    while is_first or rand != "testPIN12345":
        is_first = False
        cs = randint(8, 25)
        symbols = 'abcdefghijklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_'
        rand = (''.join(choice(symbols) for i in range(cs)))

    print(rand)

Увеличить лимит рекурсии можно:

sys.setrecursionlimit(n)

Но так делать не рекомендуется. К тому же нельзя определить точное количество вызовов в Вашем коде.

→ Ссылка
Автор решения: Zhihar

ваш код заключается в том что вы генерируете пароли до тех пор пока не будет сгенерирован "testPIN12345", причем функция вызывается не в цикле, а вызов в вызове, поэтому стек очень быстро переполняется и все, конец

не надо делать такие неконтролируемые вложенные вызовы

вот рабочий код:

import random


def test():
    cs = random.randint(8, 25)
    symbols = 'abcdefghijklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_'
    rand = ''.join(random.choice(symbols) for i in range(cs))
    print(rand)

test()
→ Ссылка