Pythonic编写包装函数的方法

时间:2017-07-11 07:07:05

标签: python

我们假设我有一个函数foo,它可以获得一些参数

def foo(width, height, depth=0):
    ...

我想编写一个包装函数来获取所有foo的参数并传递它们,例如

def goo(width, height, depth=0):
    ...
    foo(width, height, depth)
    ...

但这很难看,因为我必须重复变量的默认值。

在python中执行此操作的惯用方法是什么?

我想到了几个选项:

  1. 传递给goo一个名为foo_params的词典并致电foo(**foo_params),但由于我不知道,因此容易出错 如果所有论据都在那里

  2. 为foo编写另一个包装器,用于检查具有默认值的参数是否为None,如果是,则不会传递它们

  3. 将默认值设为常量,以免我不重复

2 个答案:

答案 0 :(得分:6)

您可以使用*args**kwargs语法传递未知数量的参数和/或关键字参数:

>>> def dec(func):
    def inner(*args, **kwargs):
        print('decorated function')
        func(*args, **kwargs)
    return inner

>>> @dec
def func(a, b):
    return a + b

>>> func(1, 2)
decorated function
>>> 

使用*args**kwargs的一个缺点是您将丢失已修饰函数的原始函数签名。例如:

>>> help(func)
Help on function inner in module __main__:

inner(*args, **kwargs)

>>> 

解决方案是使用functools.wraps()。它基本上将装饰函数中的数据复制到包装函数:

>>> from functools import wraps
>>> 
>>> def dec(func):
    @wraps(func)
    def inner(*args, **kwargs):
        print('decorated function')
        func(*args, **kwargs)
    return inner

>>> @dec
def func(a, b):
    return a + b

>>> func(1, 2)
decorated function
>>> 

您可以在下面看到,如果您现在help(func) func将显示>>> help(func) Help on function func in module __main__: func(a, b) >>> 的原始签名:

Private Var_MyProperties_Parent As Integer

Public Property MyProperties_Parent As Integer
    Get
        Return Var_MyProperties_Parent
    End Get
    Set(value As Class_Child)
        Var_MyProperties_Parent = value
        Refresh()
    End Set
End Property

答案 1 :(得分:1)

我认为您正在寻找functools's partial 功能:

from functools import partial

def foo(a,b):
    return a + b

goo = partial(foo, b = 1)

goo(5)   # returns 6