पायथन में, रिकर्सन की संख्या (रिकर्सन की अधिकतम संख्या) की ऊपरी सीमा होती है। बड़ी संख्या में कॉल के साथ पुनरावर्ती फ़ंक्शन को निष्पादित करने के लिए, सीमा को बदलना आवश्यक है। मानक पुस्तकालय के 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)
यदि आप ऊपरी सीमा से अधिक पुनरावर्तन करने का प्रयास करते हैं तो एक त्रुटि (RecursionError) उठाई जाएगी।
recu_test(950)
# Finish
# recu_test(1500)
# RecursionError: maximum recursion depth exceeded in comparison
ध्यान दें कि sys.getrecursionlimit() द्वारा प्राप्त मान सख्ती से अधिकतम संख्या में पुनरावर्तन नहीं है, लेकिन पायथन दुभाषिया की अधिकतम स्टैक गहराई है, इसलिए भले ही पुनरावर्तन की संख्या इस मान से थोड़ी कम हो, एक त्रुटि (RecursionError) होगी उठाना।
# 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
पायथन में, मानक पुस्तकालय में संसाधन मॉड्यूल का उपयोग अधिकतम स्टैक आकार को बदलने के लिए किया जा सकता है। हालांकि, संसाधन मॉड्यूल एक यूनिक्स-विशिष्ट मॉड्यूल है और इसे विंडोज़ पर उपयोग नहीं किया जा सकता है।
- Unix Specific Services — Python 3.10.0 Documentation
- resource — Resource usage information — Python 3.10.0 Documentation
Resource.getrlimit() के साथ, आप तर्क में निर्दिष्ट संसाधन की सीमा (सॉफ्ट लिमिट, हार्ड लिमिट) के टपल के रूप में प्राप्त कर सकते हैं। यहां, हम संसाधन निर्दिष्ट करते हैं। RLIMIT_STACK संसाधन के रूप में, जो वर्तमान प्रक्रिया के कॉल स्टैक के अधिकतम आकार का प्रतिनिधित्व करता है।
- resource.getrlimit() — Resource usage information — Python 3.10.0 Documentation
- resource.RLIMIT_STACK — Resource usage information — Python 3.10.0 Documentation
print(resource.getrlimit(resource.RLIMIT_STACK))
# (8388608, -1)
उदाहरण में, सॉफ्ट लिमिट 8388608 (8388608 बी = 8192 केबी = 8 एमबी) है और हार्ड लिमिट -1 (असीमित) है।
आप संसाधन की सीमा को resource.setrlimit () के साथ बदल सकते हैं। यहां, सॉफ्ट लिमिट भी -1 (कोई सीमा नहीं) पर सेट है। आप निरंतर संसाधन का उपयोग भी कर सकते हैं। असीमित सीमा का प्रतिनिधित्व करने के लिए RLIM_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
सुडो के साथ स्क्रिप्ट चलाने से मदद नहीं मिली। इसे सिस्टम द्वारा प्रतिबंधित किया जा सकता है।
सुपरयूज़र के प्रभावी यूआईडी के साथ एक प्रक्रिया बिना किसी सीमा सहित किसी भी उचित सीमा का अनुरोध कर सकती है।
हालांकि, एक अनुरोध जो सिस्टम द्वारा लगाई गई सीमा से अधिक है, उसके परिणामस्वरूप अभी भी एक ValueError होगा।
resource.setrlimit() — Resource usage information — Python 3.10.0 Documentation
विंडोज़ में संसाधन मॉड्यूल नहीं है, और मैक सिस्टम सीमाओं के कारण अधिकतम स्टैक आकार नहीं बदल सका। अगर हम किसी तरह से स्टैक का आकार बढ़ा सकते हैं, तो हमें सेगमेंटेशन फॉल्ट को हल करने में सक्षम होना चाहिए, लेकिन हम इसकी पुष्टि नहीं कर पाए हैं।