Python 找出是否调用了函数

Python 找出是否调用了函数,python,python-3.x,Python,Python 3.x,我正在用Python编程,我想知道是否可以测试代码中是否调用了函数 def example(): pass example() #Pseudocode: if example.has_been_called: print("foo bar") 如何执行此操作?如果函数可以知道自己的名称,则可以使用函数属性: def example(): example.has_been_called = True pass example.has_been_called = Fa

我正在用Python编程,我想知道是否可以测试代码中是否调用了函数

def example():
    pass
example()
#Pseudocode:
if example.has_been_called:
   print("foo bar")

如何执行此操作?

如果函数可以知道自己的名称,则可以使用函数属性:

def example():
    example.has_been_called = True
    pass
example.has_been_called = False


example()

#Actual Code!:
if example.has_been_called:
   print("foo bar")
import functools

def trackcalls(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        wrapper.has_been_called = True
        return func(*args, **kwargs)
    wrapper.has_been_called = False
    return wrapper

@trackcalls
def example():
    pass


example()

#Actual Code!:
if example.has_been_called:
   print("foo bar")
您还可以使用装饰器设置属性:

def example():
    example.has_been_called = True
    pass
example.has_been_called = False


example()

#Actual Code!:
if example.has_been_called:
   print("foo bar")
import functools

def trackcalls(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        wrapper.has_been_called = True
        return func(*args, **kwargs)
    wrapper.has_been_called = False
    return wrapper

@trackcalls
def example():
    pass


example()

#Actual Code!:
if example.has_been_called:
   print("foo bar")

这里有一个装饰程序,它将使用colorama监视您的所有函数,并返回一个漂亮的输出

try:
    import colorama
except ImportError:
    class StdClass: pass
    def passer(*args, **kwargs): pass
    colorama = StdClass()
    colorama.init = passer
    colorama.Fore = StdClass()
    colorama.Fore.RED = colorama.Fore.GREEN = ''

def check_for_use(show=False):
    if show:
        try:
            check_for_use.functions
        except AttributeError:
            return
        no_error = True
        for function in check_for_use.functions.keys():
            if check_for_use.functions[function][0] is False:
                print(colorama.Fore.RED + 'The function {!r} hasn\'t been called. Defined in "{}" '.format(function, check_for_use.functions[function][1].__code__.co_filename))
                no_error = False
        if no_error:
            print(colorama.Fore.GREEN + 'Great! All your checked function are being called!')
        return check_for_use.functions
    try:
        check_for_use.functions
    except AttributeError:
        check_for_use.functions = {}
        if colorama:
            colorama.init(autoreset=True)

    def add(function):
        check_for_use.functions[function.__name__] = [False, function]
        def func(*args, **kwargs):
            check_for_use.functions[function.__name__] = [True, function]
            function(*args, **kwargs)
        return func
    return add

@check_for_use()
def hello():
    print('Hello world!')

@check_for_use()
def bonjour(nb):
    print('Bonjour tout le monde!')


# hello(); bonjour(0)

hello()


check_for_use(True) # outputs the following
输出: 自20世纪60年代以来,功能一直存在。在python中,可以将它们用作example()函数的装饰器

import functools

@functools.lru_cache(maxsize=None)
def example():
     pass
标准的备忘录功能如下所示:

def memoize(func):
    memo = {}
    def wrapper(*args):
        if not args in memo:
            memo[args] = func(*args)
        return memo[args]
    return wrapper 
@memoize
def example():
    pass
你可以这样装饰你的功能:

def memoize(func):
    memo = {}
    def wrapper(*args):
        if not args in memo:
            memo[args] = func(*args)
        return memo[args]
    return wrapper 
@memoize
def example():
    pass
在python3.2中,可以使用而不是memoziation函数

import functools

@functools.lru_cache(maxsize=None)
def example():
     pass
我们可以用mock,mock

从unittest导入模拟
已调用def check_(func):
返回mock.mock(副作用=func)
@查一下你的电话
def总和计(a、b):
打印(a+b)
总和器(1,3)
summator.assert_调用()
assert summator.called==True
assert summator.call\u count>0
summator.assert_使用(1,3)调用_
summator.assert_调用_时带有(1,5)#错误
#AssertionError:预期调用:mock(1,5)
#实际调用:模拟(1,3)
使用标准库的一个简单示例:

从unittest.mock导入mock
def示例():
通过
示例模拟=模拟(副作用=示例)
示例_mock()
#伪代码:
如果示例_mock.called:
打印(“foo-bar”)
运行脚本后的控制台输出:

foo bar
这种方法很好,因为它不需要您修改
示例
函数本身,如果您希望在某些单元测试代码中执行此检查,而不修改源代码本身(例如存储名为的
属性,或将函数包装在装饰器中),那么这种方法非常有用

解释 如中所述,
Mock()
构造函数的
side\u effect
参数指定“调用Mock时要调用的函数”

Mock.called
属性指定“一个表示是否调用了Mock对象的布尔值”

Mock
类具有其他您可能会发现有用的属性,例如:

call\u count
:一个整数,告诉您模拟对象被调用了多少次

call_args
:这要么是无(如果尚未调用mock),要么是上次调用mock时使用的参数

call\u args\u list
:这是按顺序对模拟对象进行的所有调用的列表(因此列表的长度是调用它的次数)。在进行任何呼叫之前,它是一个空列表

Mock
类还有一些方便的方法,可以根据调用
Mock
对象的次数以及调用对象的参数来生成断言语句,例如:

assert\u使用(*args,**kwargs)调用了一次\u
:断言mock只调用了一次,并且该调用使用了指定的参数


我写了一个应用程序,它会告诉你一个函数被调用了多少次。如果需要,您可以根据自己的需要对其进行调整。您希望如何处理这些信息?很有意思的是,函数可以获得属性,因为Python中的所有内容都是对象。函数是“function”类的对象。您可以为实例分配属性,因为您不必在Python中声明变量,所以可以在运行时分配它们check@DanielBraun它将以何种方式通过mypy检查?