判断对错
如果定义了一个函数但从未调用过,那么Python会自动检测并发出警告
答案 0 :(得分:1)
其中一个问题是Python中的函数是第一类对象。所以他们的名字可以重新分配。例如:
def myfunc():
pass
a = myfunc
myfunc = 42
a()
我们还有闭包,其中一个函数由另一个函数返回,原始名称超出范围。
不幸的是,定义一个与现有函数同名的函数也是完全合法的。例如:
def myfunc(): # <<< This code is never called
pass
def myfunc():
pass
myfunc()
因此,任何跟踪都必须包含函数id
,而不仅仅是其名称 - 尽管这不会对闭包有帮助,因为id
可以重复使用。如果重新分配函数的__name__
属性,它也会得不到帮助。
您可以使用装饰器跟踪函数调用。在这里,我使用了名称和id
- id
本身不可读。
import functools
globalDict = {}
def tracecall(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
global globalDict
key = "%s (%d)" % (f.__name__, id(f))
# Count the number of calls
if key in globalDict:
globalDict[key] += 1
else:
globalDict[key] = 1
return f(*args, **kwargs)
return wrapper
@tracecall
def myfunc1():
pass
myfunc1()
myfunc1()
@tracecall
def myfunc1():
pass
a = myfunc1
myfunc1 = 42
a()
print(globalDict)
给出:
{'myfunc1 (4339565296)': 2, 'myfunc1 (4339565704)': 1}
但是只提供已调用的函数,而不是那些没有调用的函数!
那么从哪里开始呢?鉴于python的动态特性,我希望你能看到任务非常困难。但我希望我上面展示的装饰器至少可以让你诊断代码的使用方式。
答案 1 :(得分:0)
不,不是。 Python没有检测到这一点。如果要在运行时检测哪些函数被调用,可以在程序中使用全局集。在每个函数内添加要设置的函数名称。稍后您可以打印您的设置内容并检查是否已调用该功能。
答案 2 :(得分:0)
假。忽略这样做的困难和开销,没有理由说它有用。
在模块中定义的函数(即Python文件)但未在该模块中的其他位置调用的函数可能会从一个不同的模块调用,因此不会发出警告。
如果Python要分析在程序过程中运行的所有模块,并打印关于未调用的函数的警告,则可能是由于此特定运行中的输入而未调用函数,例如也许在计算器程序中有一个&#34;乘法&#34;功能,但用户只要求总结一些数字。
如果Python要分析构成程序的所有模块并注意并打印关于无法调用的函数的警告(这是不可能的,但请留在这里),那么它会警告有意使用的函数在其他计划中。例如。如果您有两个计算器程序,一个简单的计算器程序和一个高级计算器程序,可能您有一个带有效用函数的中心calc.py
,然后无法调用高级函数,如exp
和log
当它被用作简单程序的一部分时,但不应该引起警告,因为高级程序需要它们。