Python中是否有一种方法可以检查函数的签名?

21

我正在寻找一种方法来检查Python中给定函数所需的参数数量。目的是为了实现更健壮的方法,以便对我的类进行测试补丁。因此,我想要做类似于以下方式的操作:

class MyClass (object):
    def my_function(self, arg1, arg2):
        result = ... # Something complicated
        return result

def patch(object, func_name, replacement_func):
    import new

    orig_func = getattr(object, func_name)
    replacement_func = new.instancemethod(replacement_func, 
                           object, object.__class__)

    # ...
    # Verify that orig_func and replacement_func have the 
    # same signature.  If not, raise an error.
    # ...

    setattr(object, func_name, replacement_func)

my_patched_object = MyClass()
patch(my_patched_object, "my_function", lambda self, arg1: "dummy result")
# The above line should raise an error!

感谢。


“为测试修补我的类”?为什么不使用模拟对象?http://python-mock.sourceforge.net/? - S.Lott
2
我对使用模拟对象还很陌生。我“成长”于存根和补丁的使用中。我正在练习并找出何时使用哪种方法,但与此同时,我仍然有项目要完成和测试要编写 :)。 - mjumbewu
5个回答

20

inspect.getargspec 已在 Python 3 中被弃用。考虑使用类似以下的方法:

import inspect
len(inspect.signature(foo_func).parameters)

16
你可以使用:

你可以使用:

import inspect
len(inspect.getargspec(foo_func)[0])

这不会承认可变长度参数,比如:

def foo(a, b, *args, **kwargs):
    pass

现在,对于新的 Python 版本,应该使用 inspect.getfullargspec(foo)[0] - Chau Pham

5

2

我明白了。在发帖之前我做了一些搜索,但我想我应该使用更多的搜索词。对此给您带来的不便深感抱歉。 - mjumbewu
没问题。不过最好是指向其他答案,而不是在这里重复一遍。 - Richard Fearn

0
使用接受的答案,你甚至可以像这样构建整个类型:
import inspect
from typing import Callable, Any, Type, List

def ftype(func: Callable[[Any], Any]) -> Type[Callable[[Any], Any]]:
    assert callable(func)
    ret = inspect.signature(func).return_annotation
    params = list(inspect.signature(func).parameters.values())
    param_types: List[Type[Any]] = [param.annotation for param in params]
    return Callable[[*param_types], ret]

在你的代码中,你可以使用is关键字来检查类型,就像这样:
def equal_strings(text1: str, text2: str) -> bool:
    return text1 == text2

# ...

>>> my_fuction is Callable[[str, str], bool] 
True

>>> ftype(equal_strings)
typing.Callable[[str, str], bool]

然而,我的mypy对这一切都不感冒,这可能是你首次来到这里的原因。
我只是觉得这个神奇的东西很有趣。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接