简体   繁体   English

Python 额外的 print() 影响打印的计数器值

[英]Python additional print() impacts printed counter value

The below provided code shows for me unexpected and strange behavior.下面提供的代码向我展示了意外和奇怪的行为。 With not out-commented print statement the final value of the counter variable differs from the value with out-commented print statement.没有注释掉的打印语句,计数器变量的最终值与注释掉的打印语句的值不同。 How can an inserted print() impact the final value of the counter 'cnt'?插入的print()如何影响计数器“cnt”的最终值?

Here the output with the print statement printing:这里的 output 带有打印语句打印:

sys: maxRecursionDepth = 10
  > f(s) 0
>>> f(s) 1
  > f(s) 1
>>> f(s) 2
f() maxRecursionDepth =  2

And here the output with the out-commented print:在这里 output 带有注释掉的打印:

sys: maxRecursionDepth = 10
>>> f(s) 1
>>> f(s) 2
f() maxRecursionDepth =  3

And here the code which shows this for me strange effect I can't explain how it comes:这里的代码为我显示了奇怪的效果,我无法解释它是如何产生的:

from sys import getrecursionlimit, setrecursionlimit
setrecursionlimit(10)
print(f'sys: maxRecursionDepth = {getrecursionlimit()}')
cnt = 0
def f(s):
    global cnt
    #print('  >', s, cnt) # <<< CHANGES the final value of 'cnt' !!!
    cnt += 1
    print('>>>', s, cnt)
    eval(s)
# ---
try:
    f("f(s)")
except RecursionError:
    print(f'f() maxRecursionDepth =  {cnt}')
    # RecursionError: maximum recursion depth exceeded

As already pointed out by Michael Butscher in the comments the core of the confusion which lead to asking the question was to erroneously believe that only recursive calls to the function itself in a function can be a reason for an RecursionError正如Michael Butscher在评论中已经指出的那样,导致提出问题的混淆的核心是错误地认为只有在 function 中对 function 本身的递归调用可能是RecursionError的原因

The recursion limit is actually the maximum number of stack frames.递归限制实际上是堆栈帧的最大数量。 Each call to a function (even "print") temporarily adds a stack frame.每次调用 function(甚至是“打印”)都会临时添加一个堆栈帧。 If the limit is exceeded by the print-call, the exception is raised.如果打印调用超出限制,则会引发异常。 If un-commented, it happens before "cnt" is incremented, otherwise after the increment.如果未注释,则在“cnt”递增之前发生,否则在递增之后发生。

Below the evidence of the above showing that the RecursionError can and was actually caused by print() .下面的证据表明 RecursionError 可以并且实际上是由print()引起的。

>>> f(s) 1
>>> f(s) 2
Traceback (most recent call last):
  File "test.py", line 151, in <module>
    f("f(s)")
  File "test.py", line 150, in f
    eval(s)
  File "<string>", line 1, in <module>
  File "test.py", line 150, in f
    eval(s)
  File "<string>", line 1, in <module>
  File "test.py", line 149, in f
    print('>>>', s, cnt)
RecursionError: maximum recursion depth exceeded while calling a Python object
# ======================================================================
  > f(s) 0
>>> f(s) 1
  > f(s) 1
>>> f(s) 2
Traceback (most recent call last):
  File "test.py", line 151, in <module>
    f("f(s)")
  File "test.py", line 150, in f
    eval(s)
  File "<string>", line 1, in <module>
  File "test.py", line 150, in f
    eval(s)
  File "<string>", line 1, in <module>
  File "test.py", line 147, in f
    print('  >', s, cnt) # <<< CHANGES the final value of 'cnt' !!!
RecursionError: maximum recursion depth exceeded while calling a Python object

Below the code creating both of the above Tracebacks.在创建上述两个 Tracebacks 的代码下方。 Please notice that your own run of the code can lead to another result because depending on how many frames are already on the stack when running this code the code can fail at another statement as that one pointed out in above Traceback.请注意,您自己运行代码可能会导致另一个结果,因为根据运行此代码时堆栈上已有多少帧,代码可能会在另一条语句处失败,正如上面 Traceback 中指出的那样。

from sys import getrecursionlimit, setrecursionlimit
setrecursionlimit(10)
print(f'sys: maxRecursionDepth = {getrecursionlimit()}')
cnt = 0
def f(s):
    global cnt
    # print('  >', s, cnt) # <<< CHANGES the final value of 'cnt' !!!
    cnt += 1
    print('>>>', s, cnt)
    eval(s)
f("f(s)")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM