python https RecursionError详解

RecursionError: maximum recursion depth exceeded while calling a Python object

File "/root/miniconda3/envs/devops/lib/python3.8/site-packages/urllib3/connectionpool.py", line 699, in urlopen

httplib_response = self._make_request(

File "/root/miniconda3/envs/devops/lib/python3.8/site-packages/urllib3/connectionpool.py", line 382, in _make_request

self._validate_conn(conn)

File "/root/miniconda3/envs/devops/lib/python3.8/site-packages/urllib3/connectionpool.py", line 1010, in _validate_conn

conn.connect()

File "/root/miniconda3/envs/devops/lib/python3.8/site-packages/urllib3/connection.py", line 392, in connect

self.ssl_context = create_urllib3_context(

File "/root/miniconda3/envs/devops/lib/python3.8/site-packages/urllib3/util/ssl_.py", line 312, in create_urllib3_context

context.options |= options

File "/root/miniconda3/envs/devops/lib/python3.8/ssl.py", line 602, in options

super(SSLContext, SSLContext).options.__set__(self, value)

File "/root/miniconda3/envs/devops/lib/python3.8/ssl.py", line 602, in options

super(SSLContext, SSLContext).options.__set__(self, value)

File "/root/miniconda3/envs/devops/lib/python3.8/ssl.py", line 602, in options

super(SSLContext, SSLContext).options.__set__(self, value)

[Previous line repeated 468 more times]

RecursionError: maximum recursion depth exceeded while calling a Python object

注意看上面特殊颜色标注的内容,表示超过了468的深度。

问题原因:

1)代码问题,逻辑编写错误导致了递归溢出,比如代码小白,写个递归死循环了。这种情况不适用本篇文章。

2) 代码太庞大了,调用深度太深!

问题翻译解释: 超过最大递归深度,当然这个只是字面意思。其实是可以复现这个问题的

问题深度解析:

python有调用深度控制,默认是1000,我们可以通过sys.setrecursionlimit(N)来设置调用深度为N;报错的意思虽然是说递归深度超过限制,但不要局限于递归问题,其实也是调用堆栈的问题,涉及到C的一些基础....

比如以下代码,设置递归深度为20时,会报错RecursionError,然后改成21便可以正常结束。这里如果不调用traceback函数,其实只需要设置成8就足够了。

import sys
#使用内置的包traceback可以获得堆栈信息
import traceback
#改成21的深度就可以正常,
sys.setrecursionlimit(20)
def a():
    index = 0
    #到这个函数只需要8层就足够了,但是下面的traceback.format_stack里面还有,超出了当前运行的py设置的深度,一样会报错
    #不要这段for循环,上面setrecursionlimit(8)就可以了
    for line in traceback.format_stack():
        index +=1
        print("当前位置调用深度:%s,详细堆栈:%s" % (index, line.strip()))
    return "调用结束"
def b():
    return a()
def c():
    return b()
def d():
    return c()
def e():
    return d()
def f():
    return e()
print(f())

运行结果如下:

python https RecursionError详解_第1张图片

正常的输出结果如下:

调用深度:1,详细堆栈:File "D:/my_code/pycde/testtss.py", line 21, in 
    print(f())
调用深度:2,详细堆栈:File "D:/my_code/pycde/testtss.py", line 19, in f
    return e()
调用深度:3,详细堆栈:File "D:/my_code/pycde/testtss.py", line 17, in e
    return d()
调用深度:4,详细堆栈:File "D:/my_code/pycde/testtss.py", line 15, in d
    return c()
调用深度:5,详细堆栈:File "D:/my_code/pycde/testtss.py", line 13, in c
    return b()
调用深度:6,详细堆栈:File "D:/my_code/pycde/testtss.py", line 11, in b
    return a()
调用深度:7,详细堆栈:File "D:/my_code/pycde/testtss.py", line 6, in a
    for line in traceback.format_stack():
调用结束

解决方案:

如果看懂了解析,就明白了为什么会报错RecursionError,一般用开源的项目,或者项目架构的过深,就会导致层层套娃。

#设置递归深度为很大很大,比如设置成10000。正常的程序架构都不会调用深度超过10000

不要设置太大!这个机制是为了避免真的出现代码逻辑问题时,无限的递归死循环导致OOM系统崩溃。内存CPU打爆=>会出现什么结果? 嗯,很卡,然后你logout一下就登不进去了,然后就哦豁挂了,,,

import sys
print(sys.getrecursionlimit())
sys.setrecursionlimit(10000)

django项目只需要在manage.py的上面设置这个就可以了

至于网上说这个是临时解决的方案,其实就是永久方案.,大部分文章是抄袭之后知其然不知其所以然,所以觉得没有永久解决问题。

常见发生的库有哪些

与https有关的模块,真的很深.... boto3 玩转 amazon 就几百层。然后钉钉关联的模块,但凡用到https的,很多会调用到ssl模块,也很深

你可能感兴趣的:(Python,python)