python - 强制特定函数签名

标签 python parameter-passing overloading named-parameters

我刚刚发现自己在写这样的代码:

def register(self, *,  # * enforces keyword-only parameters
             key_value_container:dict=None,    # legal parameter set #1
             key:str=None, value=None):        # legal parameter set #2

    # enforce one of the parameter sets
    if not ((key_value_container is not None and 
             key is None and value is None) or
            (key is not None and value is not None and 
             key_value_container is None)):
        raise TypeError('provide (key_value_container) or (key/value')

    # handle each legal parameter setf
    if key_value_container is not None:
        for _k, _s in key_value_container.items():
            self.register(_k, _s)
    else:
        do_something_with(key, value)

我的目标是拥有方法 register() 的两个签名:它应该采用一个 key 和一个 value 或某个容器一些键和值,例如一个字典

参数中的*至少迫使我提供命名参数,但不需要提供给定数量的参数甚至给定的集合参数

当然,我可以(应该)提供两种具有不同名称和签名的方法,而不是一种。

但是,如果我想(必须)提供一种具有多个参数语义的方法/函数 - 使其可见并强制执行的最佳方法是什么?

详细:

  • 是否可以在自动完成文档中明确哪些是合法的参数组合?
  • 如何检查(使用尽可能少的样板代码)是否提供了一种组合?

最佳答案

为了避免样板代码,您可以这样做:编写指定不同签名的附加函数。然后有一个redirect辅助函数,根据参数匹配的签名将参数从主函数发送到附加函数。

它仍然不是特别优雅。如果概括这一点,您还需要考虑如何处理 None 是您可能想要传递的有效参数的情况。

from inspect import getargspec
class Eg(object):
    def register(self, key_value_container=None, key=None, value=None):
        return redirect(locals(), [self.register_dict, self.register_single])

    def register_dict(self, key_value_container=None):
        print('register dict', key_value_container)

    def register_single(self, key=None, value=None):
        print('register single', key, value)

def redirect(params, functions):
    provided = {k for k, v in params.items() if v is not None}
    for function in functions:
        if set(getargspec(function).args) == provided:
            return function(**{k: params[k] for k in provided if k != 'self'})
    raise TypeError('wrong configuration provided') 
    # This error could be expanded to explain which signatures are allowed       

a = Eg()
a.register(key='hi', value='there')
a.register(key_value_container={'hi': 'there'})

关于python - 强制特定函数签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35913035/

相关文章:

python - Flask-登录文档 : LoginForm()

arrays - 如何将数组值作为过程参数传递?

C++,重载 std::swap,编译器错误,VS 2010

c++ - 重载 operator<< operator== 和 operator!=

python - 按位循环右移

python - 最小总容器大小 Python

python - 如何使用 Python post 请求和 Telegram 机器人在 Telegram 上发送具有 InlineKeyboardMarkup 的照片

python - 为什么拆包比传入列表更受欢迎

c# - 使用 ref 关键字传递给方法时结构是否被装箱?

c++ - 出现错误 C2679 : binary '+=' : no operator found which takes a right-hand operand of type 'int' 的问题