ਪਾਈਥਨ ਰੀਕਰਸ਼ਨ ਸੀਮਾ ਦੀ ਜਾਂਚ ਕਰੋ ਅਤੇ ਬਦਲੋ (ਉਦਾਹਰਨ ਲਈ 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)

ਜੇਕਰ ਤੁਸੀਂ ਉਪਰਲੀ ਸੀਮਾ ਤੋਂ ਵੱਧ ਦੁਹਰਾਓ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਹੋ ਤਾਂ ਇੱਕ ਤਰੁੱਟੀ (RecursionError) ਉਠਾਈ ਜਾਵੇਗੀ।

recu_test(950)
# Finish

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

ਨੋਟ ਕਰੋ ਕਿ sys.getrecursionlimit() ਦੁਆਰਾ ਪ੍ਰਾਪਤ ਕੀਤਾ ਮੁੱਲ ਸਖਤੀ ਨਾਲ ਆਵਰਤੀਆਂ ਦੀ ਅਧਿਕਤਮ ਸੰਖਿਆ ਨਹੀਂ ਹੈ, ਪਰ ਪਾਈਥਨ ਦੁਭਾਸ਼ੀਏ ਦੀ ਅਧਿਕਤਮ ਸਟੈਕ ਡੂੰਘਾਈ ਹੈ, ਇਸ ਲਈ ਭਾਵੇਂ ਦੁਹਰਾਓ ਦੀ ਸੰਖਿਆ ਇਸ ਮੁੱਲ ਤੋਂ ਥੋੜ੍ਹੀ ਘੱਟ ਹੈ, ਇੱਕ ਗਲਤੀ (RecursionError) ਹੋਵੇਗੀ। ਉਭਾਰਿਆ ਜਾਵੇ।

再帰限界は、再帰の限界ではなく、pythonインタープリタのスタック最大深度。
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() ਦੇ ਨਾਲ, ਤੁਸੀਂ ਆਰਗੂਮੈਂਟ ਵਿੱਚ ਦਰਸਾਏ ਸਰੋਤ ਦੀ ਸੀਮਾ ਨੂੰ (ਨਰਮ ਸੀਮਾ, ਸਖ਼ਤ ਸੀਮਾ) ਦੇ ਰੂਪ ਵਿੱਚ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ। ਇੱਥੇ, ਅਸੀਂ ਸਰੋਤ ਵਜੋਂ RLIMIT_STACK ਨੂੰ ਨਿਸ਼ਚਿਤ ਕਰਦੇ ਹਾਂ, ਜੋ ਮੌਜੂਦਾ ਪ੍ਰਕਿਰਿਆ ਦੇ ਕਾਲ ਸਟੈਕ ਦੇ ਅਧਿਕਤਮ ਆਕਾਰ ਨੂੰ ਦਰਸਾਉਂਦਾ ਹੈ।

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

ਉਦਾਹਰਨ ਵਿੱਚ, ਨਰਮ ਸੀਮਾ 8388608 (8388608 B = 8192 KB = 8 MB) ਹੈ ਅਤੇ ਸਖ਼ਤ ਸੀਮਾ -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
ਸੂਡੋ ਨਾਲ ਸਕ੍ਰਿਪਟ ਚਲਾਉਣ ਨਾਲ ਕੋਈ ਲਾਭ ਨਹੀਂ ਹੋਇਆ। ਇਹ ਸਿਸਟਮ ਦੁਆਰਾ ਪ੍ਰਤਿਬੰਧਿਤ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ.

ਇੱਕ ਸੁਪਰਯੂਜ਼ਰ ਦੀ ਪ੍ਰਭਾਵੀ UID ਵਾਲੀ ਇੱਕ ਪ੍ਰਕਿਰਿਆ ਕਿਸੇ ਵੀ ਵਾਜਬ ਸੀਮਾ ਦੀ ਬੇਨਤੀ ਕਰ ਸਕਦੀ ਹੈ, ਜਿਸ ਵਿੱਚ ਕੋਈ ਸੀਮਾ ਨਹੀਂ ਹੈ।
ਹਾਲਾਂਕਿ, ਇੱਕ ਬੇਨਤੀ ਜੋ ਸਿਸਟਮ ਦੁਆਰਾ ਲਗਾਈ ਗਈ ਸੀਮਾ ਤੋਂ ਵੱਧ ਜਾਂਦੀ ਹੈ ਤਾਂ ਵੀ ਇੱਕ ValueError ਦਾ ਨਤੀਜਾ ਹੋਵੇਗਾ।
resource.setrlimit() — Resource usage information — Python 3.10.0 Documentation

ਵਿੰਡੋਜ਼ ਕੋਲ ਸਰੋਤ ਮੋਡੀuleਲ ਨਹੀਂ ਹੈ, ਅਤੇ ਸਿਸਟਮ ਦੀਆਂ ਸੀਮਾਵਾਂ ਦੇ ਕਾਰਨ ਮੈਕ ਅਧਿਕਤਮ ਸਟੈਕ ਆਕਾਰ ਨੂੰ ਨਹੀਂ ਬਦਲ ਸਕਿਆ. ਜੇ ਅਸੀਂ ਕਿਸੇ ਤਰੀਕੇ ਨਾਲ ਸਟੈਕ ਦਾ ਆਕਾਰ ਵਧਾ ਸਕਦੇ ਹਾਂ, ਤਾਂ ਸਾਨੂੰ ਵਿਭਾਜਨ ਨੁਕਸ ਨੂੰ ਹੱਲ ਕਰਨ ਦੇ ਯੋਗ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ, ਪਰ ਅਸੀਂ ਇਸਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਦੇ ਯੋਗ ਨਹੀਂ ਹੋਏ.