python - 我怎样才能确保对函数的递归调用是我认为的那样?

标签 python python-3.x

如何确保对函数的递归调用是我认为的那样?

例如,假设我有:

def foo(x):
    if x <= 1:
        return
    foo(x - 1)

如何确保最内层的嵌套 foo 与最外层的调用者相同?从技术上讲,最内层的嵌套 foo 是指 globals() 中的 foo。原始的 foo 可能会在以后的某个时候意外地被隐藏。如果它具有非常短的常用函数名称,则风险特别高,例如:

  • pprint(“ pretty-print ”)
  • “调试”
  • “ sanitizer ”
  • “干净”
  • 等..

下面显示了为什么有时会出现问题的示例:

# scroll down until you get to the text which says `BEGIN`
# just ignore the code until then...

import sys 
wes = string.whitespace.replace(" ", "") # white except space   
remove_white = lambda stryng, *, re=re, string=string, wes = wes: re.sub('[' + wes + ']', '', stryng)    
# keep scrolling down... to `BEGIN`   
_print  = lambda *args, strm=sys.stdout.write, end="\n",: strm(' '.join(
        (remove_white(str(arg).strip()) for arg in args)
    ) + end)
# ______  _____  _____  _____  _   _ 
# | ___ \|  ___||  __ \|_   _|| \ | |
# | |_/ /| |__  | |  \/  | |  |  \| |
# | ___ \|  __| | | __   | |  | . ` |
# | |_/ /| |___ | |_\ \ _| |_ | |\  |
# \____/ \____/  \____/ \___/ \_| \_/
# 
# okay you can stop scrolling now!                                   
#
def foo(beer_count):
    beer_count = float(beer_count)
    print(beer_count, "bottle(s) of beer on the wall!")
    if beer_count <= 1:
        return
    foo(beer_count - 1)

_print("begin everything working okay.\n", 40*"#")
foo(4)
_print(40*"#", "end everything working okay.")

_print("\n\nbegin \u00B00o NIgHtMaRe o0\u00B0\n", 40*"#")
foo_alias = foo
foo = lambda beer_count: print(beer_count**0.5, "bottle(s) of beer on the wall!")
foo_alias(4)
_print(40*"#", "end \u00B0nIgHtMaRe\u00B0 \n\n")

程序员如何防止 foo 被隐藏...错误 ...也许不是“防止”,但是处理它?<​​/p>

我最好的尝试都是惨败:

import inspect
def foo(x):
    if x <= 1:
        return
    ########################################
    frame  = inspect.currentframe()
    framer = inspect.stack()[0]
    try:
        print("this is the function name, not a reference to the actual function:", framer.function)
    finally:
        del frame
    ##########################################
    foo(x - 1)

foo(10)

以下也不起作用...

def foo(x):
    if x <= 1:
        return
    foo.f(x - 1)
foo.f = foo

最佳答案

使用可调用对象而不是函数怎么样?

类似于:

class Recurser:
    def __call__(self, n):
        if n <= 1:
            print('.')
        else:
            print('.', end='')
            self(n-1)
recurse = Recurser()
recurse(4)  # ....
b = recurse
b(4) # ....
def recurse(n):
     print('OH NO')
b(4) # ....

或者,对于您的示例:

class BeerCounter:
    def __call__(self, beer_count):
        beer_count = float(beer_count)
        print(beer_count, "bottle(s) of beer on the wall!")
        if beer_count <= 1:
            return
        self(beer_count - 1)
foo = BeerCounter()

避免噩梦。

关于python - 我怎样才能确保对函数的递归调用是我认为的那样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58534179/

相关文章:

python - Django REST 序列化程序和来自自定义模型字段的额外属性

python - 在删除子字符串之前检查它是否存在会更快吗?

python - 使用 Pandas Melt() 以两组数据为中心

python - 如何让 Python-Telegram Bot 在没有收到命令的情况下发送消息?

python - Python2/3 中 __new__ 和 __init__ 顺序的区别

python - 值错误: cannot compute LDA over an empty collection (no terms)

python - 如何vlookup值并获取右侧的值

python-3.x - 如何在每个元素列表上用 "_"替换空白-Python

python-3.x - Dataproc 集群创建失败,出现 PIP 错误 "Could not build wheels"

Python webdriver 库未连接到 chromedriver -- "Can not connect to the Service/usr/local/bin/chromedriver"