我正在尝试编写一个文档测试工具,用于检查文档字符串是否与实际的函数签名(以及其他内容)匹配.但是,我遇到了一些障碍.我无法找到一种方法来确定给定的函数是否属于某个类.
import inspect
def func1():
pass
class Foo:
def method(self):
pass
print(inspect.ismethod(func1)) # prints False
print(inspect.ismethod(Foo().method)) # prints True
print(inspect.ismethod(Foo.method)) # prints False - I want something that prints True here
问题是方法通常将self作为其第一个参数,并且从未记录(由于显而易见的原因).这会导致我的测试失败,因为他们遇到了未记录的参数.
我宁愿不显式检查第一个参数是否被称为self并跳过它,因为a)没有什么能阻止函数有一个名为self的参数和b)名称self本身是一个约定问题(所以你可以有一个方法使用名为this_is_definitely_not_self的第一个参数,我的工具在任何一种情况下都会失败.我也不能只是初始化一个对象并检查该函数是否是一个方法,因为这会因为在__init__中获取所需参数的任何类而失败.
所以问题是,在实际绑定到对象之前,有什么方法可以检测函数是否是一个方法?或者我是否需要让自己只是检查第一个参数是否被称为self?
最佳答案 一个选项是
__qualname__
.对于方法,这包括您可以使用的类名.这是添加内容的原因之一:
07001
The qualified name of the class, function, method, descriptor, or generator instance.
有关此属性的更多信息,请参见PEP 3155’s proposal.
当然,由于在类定义期间设置了__qualname__,因此当函数动态添加到类时,可能会出现误报.所以,这个答案基本上涵盖了一个函数是否已在类中定义的问题.
因此,没有明确的方法来检测这一点,因为在类中定义并通过类访问的函数和类外的函数没有区别. (大多数情况下除了__qualname__).
一个明智的做法是使用__qualname__作为“快速”检查,以查看是否已在类中定义了一个函数,如果该函数为False,则回退到使用inspect.signature
function检查self和签名中的“self” (FUNC).parameters.
你将无法涵盖所有情况,这是Python,我可以做任何我喜欢的事情.据称,我们都同意成年人的意见. 🙂