នៅក្នុង Python មានដែនកំណត់ខាងលើចំពោះចំនួននៃការផ្សាយឡើងវិញ (ចំនួនអតិបរមានៃការផ្សាយឡើងវិញ)។ ដើម្បីប្រតិបត្តិមុខងារហៅចេញជាមួយចំនួនច្រើន វាចាំបាច់ត្រូវផ្លាស់ប្តូរកម្រិតកំណត់។ ប្រើមុខងារនៅក្នុងម៉ូឌុល sys នៃបណ្ណាល័យស្តង់ដារ។
ចំនួននៃការធ្វើឡើងវិញក៏ត្រូវបានកំណត់ដោយទំហំជង់ផងដែរ។ នៅក្នុងបរិយាកាសមួយចំនួន ម៉ូឌុលធនធាននៃបណ្ណាល័យស្តង់ដារអាចត្រូវបានប្រើដើម្បីផ្លាស់ប្តូរទំហំជង់អតិបរមា (វាដំណើរការលើអ៊ូប៊ុនទូ ប៉ុន្តែមិនមែននៅលើ Windows ឬ mac ទេ)។
ព័ត៌មានខាងក្រោមត្រូវបានផ្តល់ជូននៅទីនេះ។
- ទទួលបានដែនកំណត់ខាងលើនៃចំនួនការផ្សាយឡើងវិញបច្ចុប្បន្ន៖
sys.getrecursionlimit()
- ផ្លាស់ប្តូរដែនកំណត់ខាងលើនៃចំនួននៃការផ្សាយឡើងវិញ៖
sys.setrecursionlimit()
- ផ្លាស់ប្តូរទំហំអតិបរមានៃជង់៖
resource.setrlimit()
កូដគំរូកំពុងដំណើរការលើអ៊ូប៊ុនទូ។
ទទួលបានដែនកំណត់ការហៅឡើងវិញបច្ចុប្បន្ន៖ sys.getrecursionlimit()
ដែនកំណត់ការហៅឡើងវិញបច្ចុប្បន្នអាចទទួលបានជាមួយ sys.getrecursionlimit()។
import sys
import resource
print(sys.getrecursionlimit())
# 1000
ក្នុងឧទាហរណ៍ ចំនួនអតិបរមានៃការផ្សាយឡើងវិញគឺ 1000 ដែលអាចប្រែប្រួលអាស្រ័យលើបរិយាកាសរបស់អ្នក។ ចំណាំថាធនធានដែលយើងកំពុងនាំចូលនៅទីនេះនឹងត្រូវបានប្រើនៅពេលក្រោយ ប៉ុន្តែមិនមែននៅលើ Windows ទេ។
ជាឧទាហរណ៍ យើងនឹងប្រើមុខងារ recursive សាមញ្ញខាងក្រោម។ ប្រសិនបើចំនួនគត់វិជ្ជមាន 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() មិនមែនជាចំនួនអតិបរមានៃការផ្សាយឡើងវិញនោះទេ ប៉ុន្តែជម្រៅជង់អតិបរមារបស់អ្នកបកប្រែ Python ដូច្នេះបើទោះបីជាចំនួននៃការផ្សាយឡើងវិញតិចជាងតម្លៃនេះបន្តិចក៏ដោយ កំហុស (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
នៅក្នុង Python ម៉ូឌុលធនធាននៅក្នុងបណ្ណាល័យស្តង់ដារអាចត្រូវបានប្រើដើម្បីផ្លាស់ប្តូរទំហំជង់អតិបរមា។ ទោះយ៉ាងណាក៏ដោយ ម៉ូឌុលធនធានគឺជាម៉ូឌុលជាក់លាក់របស់យូនីក ហើយមិនអាចប្រើនៅលើវីនដូបានទេ។
- Unix Specific Services — Python 3.10.0 Documentation
- resource — Resource usage information — Python 3.10.0 Documentation
ជាមួយនឹង resource.getrlimit() អ្នកអាចទទួលបានដែនកំណត់នៃធនធានដែលបានបញ្ជាក់នៅក្នុងអាគុយម៉ង់ជា tuple នៃ (ដែនកំណត់ទន់ ដែនកំណត់រឹង)។ នៅទីនេះ យើងបញ្ជាក់ resource.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 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 (គ្មានដែនកំណត់) សម្រាប់ការពិសោធន៍សាមញ្ញ ប៉ុន្តែតាមពិត វានឹងមានសុវត្ថិភាពជាងក្នុងការកំណត់វាឱ្យមានតម្លៃសមស្រប។
លើសពីនេះទៀតនៅពេលដែលខ្ញុំព្យាយាមកំណត់ដែនកំណត់ទន់គ្មានដែនកំណត់នៅលើ mac របស់ខ្ញុំផងដែរ កំហុសខាងក្រោមបានកើតឡើង។ValueError: not allowed to raise maximum limit
ការដំណើរការស្គ្រីបដោយប្រើ sudo មិនអាចជួយបានទេ។ វាអាចត្រូវបានកម្រិតដោយប្រព័ន្ធ។
ដំណើរការជាមួយ UID ដ៏មានប្រសិទ្ធភាពនៃអ្នកប្រើប្រាស់ជាន់ខ្ពស់អាចស្នើសុំដែនកំណត់សមហេតុផលណាមួយ រួមទាំងគ្មានដែនកំណត់ផងដែរ។
ទោះយ៉ាងណាក៏ដោយ សំណើដែលលើសពីដែនកំណត់ដែលកំណត់ដោយប្រព័ន្ធនឹងនៅតែបណ្តាលឱ្យមានកំហុសតម្លៃ។
resource.setrlimit() — Resource usage information — Python 3.10.0 Documentation
Windows មិនមានម៉ូឌុលធនធានទេ ហើយ mac មិនអាចផ្លាស់ប្តូរទំហំជង់អតិបរមាបានទេ ដោយសារការកំណត់ប្រព័ន្ធ។ ប្រសិនបើយើងអាចបង្កើនទំហំជង់ដោយមធ្យោបាយមួយចំនួន យើងគួរតែអាចដោះស្រាយកំហុសនៃការបែងចែក ប៉ុន្តែយើងមិនអាចបញ្ជាក់រឿងនេះបានទេ។