पायथन पुनरावृत्ती मर्यादा तपासा आणि बदला (उदा. Sys.setrecursionlimit)

व्यवसाय

पायथनमध्ये, पुनरावृत्तींच्या संख्येची एक उच्च मर्यादा आहे (पुनरावृत्तीची जास्तीत जास्त संख्या). मोठ्या संख्येने कॉलसह पुनरावृत्ती कार्य कार्यान्वित करण्यासाठी, मर्यादा बदलणे आवश्यक आहे. मानक लायब्ररीच्या sys मॉड्यूलमधील फंक्शन्स वापरा.

पुनरावृत्तीची संख्या देखील स्टॅक आकाराने मर्यादित आहे. काही वातावरणात, स्टँडर्ड लायब्ररीचे रिसोर्स मॉड्यूल जास्तीत जास्त स्टॅक आकार बदलण्यासाठी वापरले जाऊ शकते (हे उबंटूवर काम केले, परंतु विंडोज किंवा मॅकवर नाही).

खालील माहिती येथे दिली आहे.

  • पुनरावृत्तीच्या वर्तमान संख्येची वरची मर्यादा मिळवा:sys.getrecursionlimit()
  • पुनरावृत्तीच्या संख्येची वरची मर्यादा बदला:sys.setrecursionlimit()
  • स्टॅकचा कमाल आकार बदला:resource.setrlimit()

नमुना कोड उबंटू वर चालू आहे.

वर्तमान पुनरावृत्ती मर्यादा मिळवा: sys.getrecursionlimit ()

वर्तमान पुनरावृत्ती मर्यादा sys.getrecursionlimit () सह मिळवता येते.

import sys
import resource

print(sys.getrecursionlimit())
# 1000

उदाहरणात, पुनरावृत्तीची जास्तीत जास्त संख्या 1000 आहे, जी आपल्या वातावरणानुसार बदलू शकते. लक्षात घ्या की आम्ही येथे आयात केलेले संसाधन नंतर वापरले जाईल, परंतु विंडोजवर नाही.

उदाहरण म्हणून, आम्ही खालील साधे पुनरावृत्ती कार्य वापरू. जर धनात्मक पूर्णांक n हा युक्तिवाद म्हणून निर्दिष्ट केला असेल, तर कॉलची संख्या n वेळा असेल.

def recu_test(n):
    if n == 1:
        print('Finish')
        return
    recu_test(n - 1)

आपण वरच्या मर्यादेपेक्षा जास्त पुनरावृत्ती करण्याचा प्रयत्न केल्यास एक त्रुटी (रिकर्सन एरर) उठवली जाईल.

recu_test(950)
# Finish

# recu_test(1500)
# RecursionError: maximum recursion depth exceeded in comparison

लक्षात घ्या की sys.getrecursionlimit () द्वारे प्राप्त केलेले मूल्य कडकपणे पुनरावृत्तीची संख्या नाही, परंतु पायथन दुभाषीची जास्तीत जास्त स्टॅक खोली आहे, म्हणून जरी पुनरावृत्तीची संख्या या मूल्यापेक्षा थोडी कमी असली तरी त्रुटी (रिकर्सन एरर) होईल उठवले जा.

帰 限界 は 、 の 、 th th th अजगर イ ン タ ー プ
python – Max recursion is not exactly what sys.getrecursionlimit() claims. How come? – Stack Overflow

# recu_test(995)
# RecursionError: maximum recursion depth exceeded while calling a Python object

पुनरावृत्ती मर्यादा बदला: sys.setrecursionlimit ()

पुनरावृत्तीच्या संख्येची वरची मर्यादा sys.setrecursionlimit () द्वारे बदलली जाऊ शकते. वरील मर्यादा एक युक्तिवाद म्हणून निर्दिष्ट केली आहे.

सखोल पुनरावृत्ती करण्यास अनुमती देते.

sys.setrecursionlimit(2000)

print(sys.getrecursionlimit())
# 2000

recu_test(1500)
# Finish

निर्दिष्ट केलेली उच्च मर्यादा खूप लहान किंवा खूप मोठी असल्यास, एक त्रुटी येईल. ही मर्यादा (मर्यादेच्या वरच्या आणि खालच्या मर्यादा स्वतः) पर्यावरणानुसार बदलते.

मर्यादेचे जास्तीत जास्त मूल्य प्लॅटफॉर्मवर अवलंबून असते. आपल्याला खोल पुनरावृत्तीची आवश्यकता असल्यास, आपण प्लॅटफॉर्मद्वारे समर्थित श्रेणीमध्ये मोठे मूल्य निर्दिष्ट करू शकता, परंतु हे मूल्य खूप मोठे असल्यास क्रॅश होईल याची जाणीव ठेवा.
If the new limit is too low at the current recursion depth, a RecursionError exception is raised.
sys.setrecursionlimit() — System-specific parameters and functions — Python 3.10.0 Documentation

sys.setrecursionlimit(4)
print(sys.getrecursionlimit())
# 4

# sys.setrecursionlimit(3)
# RecursionError: cannot set the recursion limit to 3 at the recursion depth 1: the limit is too low

sys.setrecursionlimit(10 ** 9)
print(sys.getrecursionlimit())
# 1000000000

# sys.setrecursionlimit(10 ** 10)
# OverflowError: signed integer is greater than maximum

पुढील स्पष्टीकरणानुसार, पुनरावृत्तीची जास्तीत जास्त संख्या स्टॅकच्या आकाराद्वारे देखील मर्यादित आहे.

स्टॅकचा जास्तीत जास्त आकार बदला: resource.setrlimit ()

जरी sys.setrecursionlimit () मध्ये मोठे मूल्य सेट केले असले तरी, पुनरावृत्तीची संख्या मोठी असल्यास ती अंमलात आणली जाऊ शकत नाही. विभाजन दोष खालीलप्रमाणे उद्भवते.

sys.setrecursionlimit(10 ** 9)
print(sys.getrecursionlimit())
# 1000000000
recu_test(10 ** 4)
# Finish

# recu_test(10 ** 5)
# Segmentation fault

पायथनमध्ये, मानक ग्रंथालयातील संसाधन मॉड्यूलचा वापर जास्तीत जास्त स्टॅक आकार बदलण्यासाठी केला जाऊ शकतो. तथापि, रिसोर्स मॉड्यूल हे युनिक्स-विशिष्ट मॉड्यूल आहे आणि विंडोजवर वापरले जाऊ शकत नाही.

Resource.getrlimit () सह, तुम्ही युक्तिवादात निर्दिष्ट केलेल्या संसाधनाची मर्यादा (मऊ मर्यादा, कठोर मर्यादा) म्हणून मिळवू शकता. येथे, आम्ही resource.RLIMIT_STACK हे संसाधन म्हणून निर्दिष्ट करतो, जे वर्तमान प्रक्रियेच्या कॉल स्टॅकच्या कमाल आकाराचे प्रतिनिधित्व करते.

print(resource.getrlimit(resource.RLIMIT_STACK))
# (8388608, -1)

उदाहरणामध्ये, मऊ मर्यादा 8388608 (8388608 B = 8192 KB = 8 MB) आणि कठीण मर्यादा -1 (अमर्यादित) आहे.

तुम्ही resource.setrlimit () सह संसाधनाची मर्यादा बदलू शकता. येथे, सॉफ्ट मर्यादा देखील -1 (मर्यादा नाही) वर सेट केली आहे. आपण अमर्यादित मर्यादेचे प्रतिनिधित्व करण्यासाठी स्थिर संसाधन. RIM_INFINIT देखील वापरू शकता.

स्टॅकचा आकार बदलण्याआधी विभाजन बिघाडामुळे करता येत नसलेली खोल पुनरावृत्ती आता केली जाऊ शकते.

resource.setrlimit(resource.RLIMIT_STACK, (-1, -1))

print(resource.getrlimit(resource.RLIMIT_STACK))
# (-1, -1)

recu_test(10 ** 5)
# Finish

येथे, साध्या प्रयोगासाठी सॉफ्ट मर्यादा -1 (मर्यादा नाही) वर सेट केली आहे, परंतु प्रत्यक्षात, योग्य मूल्यापर्यंत मर्यादित करणे अधिक सुरक्षित असेल.

याव्यतिरिक्त, जेव्हा मी माझ्या मॅकवर अमर्यादित सॉफ्ट मर्यादा सेट करण्याचा प्रयत्न केला तेव्हा खालील त्रुटी आली.ValueError: not allowed to raise maximum limit
सुडो सह स्क्रिप्ट चालवण्यास मदत झाली नाही. हे सिस्टमद्वारे प्रतिबंधित केले जाऊ शकते.

सुपरयुझरच्या प्रभावी UID असलेली प्रक्रिया कोणत्याही मर्यादेसह कोणत्याही वाजवी मर्यादेची विनंती करू शकते.
तथापि, सिस्टीमने लादलेली मर्यादा ओलांडणारी विनंती अजूनही व्हॅल्यू एररमध्ये परिणाम करेल.
resource.setrlimit() — Resource usage information — Python 3.10.0 Documentation

विंडोजमध्ये रिसोर्स मॉड्यूल नाही आणि सिस्टम मर्यादांमुळे मॅक कमाल स्टॅक आकार बदलू शकत नाही. जर आम्ही काही प्रकारे स्टॅकचा आकार वाढवू शकलो, तर आम्ही विभाजन दोष सोडवण्यास सक्षम असले पाहिजे, परंतु आम्ही याची पुष्टी करू शकलो नाही.