繁体   English   中英

带有未知参数的Python包装函数

[英]Python wrap function with unknown arguments

如果我有这个功能:

def foo(arg_one, arg_two):
    pass

我可以像这样包装它:

def bar(arg_one, arg_two):
    return foo(arg_one, arg_two)

foo = bar

是否有可能在不知道foo必需参数的情况下这样做,如果是这样,怎么做?

您可以使用参数解包运算符(或其他任何调用的运算符):

def bar(*args, **kwargs):
    return foo(*args, **kwargs)

如果您不打算传递任何关键字参数,则可以删除**kwargs

你可以使用*args**kwargs

def bar(*args, **kwargs):
    return foo(*args, **kwargs)

args是位置参数列表。

kwargs是关键字参数的字典。

请注意,调用那些变量argskwargs只是一个命名约定。 ***为解包参数做了所有的魔力。

另见:

这是另一个略微通用的用例(除了Blender的回答):

通常在扩展对象时在OOP中,实际上需要覆盖方法并且(小心地)扩展甚至更改签名 (扩展方法的参数的顺序和数量),例如在作为对象构造函数的__init__()方法中。

以下是如何为此目的应用* args,** kwds的示例:

class Foo(object):
    def __init(self, foo_positional_arg, foo_optional_arg=None):
        pass


class Bar(Foo):

    def __init__(self, bar_postional_arg, bar_optional_arg=None, *args, **kwds):
        self.bar_postional_arg = bar_postional_arg
        self.bar_optional_arg = bar_optional_arg
        super(Bar, self).__init__(*args, **kwds)

实际上,实际上可以确实改变签名的顺序或者从先前(包装的)完整或部分签名中捕获参数。

def __init__(self, bar_postional_arg, foo_positional, foo_optional_arg=False, bar_optional_arg=None, *args, **kwds):

这再次证明了python函数(和方法)中的* args,** kwds机制是多么灵活(!)。

除了alecxe的答案之外 ,如果你希望你的包装器保留签名(换句话说,它的用户看起来好像是包装函数),你可能希望看一下functools.wraps及其替换品makefun.wraps ,它修复了一些缺点,并将其用法扩展到您想要修改签名的情况。 请参阅此处 ,了解差异的简短说明。 顺便说一下,我是makefun的作者;)

这就是你编码的方式:

from makefun import wraps

@wraps(foo)
def bar(*args, **kwargs):
    return foo(*args, **kwargs)

暂无
暂无

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

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