检查函数是否属于一个类

Chi*_*chi 5 python reflection python-3.x

我正在尝试编写一个文档测试工具,用于检查文档字符串是否与实际函数签名(除其他外)匹配。然而,我遇到了一些障碍。我找不到一种方法来确定给定函数是否属于一个类。

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
Run Code Online (Sandbox Code Playgroud)

问题是方法通常将self其作为第一个参数,而这从未被记录(出于明显的原因)。这会导致我的测试失败,因为它们会遇到未记录的参数。

我宁愿不显式检查第一个参数是否被调用self并跳过它,因为a)没有什么可以阻止函数调用参数self,b)名称self本身是一个约定问题(所以你可以有一个带有第一个参数的方法)称为this_is_definitely_not_self) 的参数,我的工具在任何一种情况下都会失败。我也不能只初始化一个对象并检查该函数是否是一个方法,因为对于任何在其__init__.

所以问题是,有什么方法可以在函数实际绑定到对象之前检测它是否是方法?或者我是否需要只检查第一个参数是否被调用self

Jim*_*ard 6

一种选择是__qualname__。对于方法,这包括您可以使用的类名称。这就是添加它的原因之一:

definition.__qualname__

类、函数、方法、描述符或生成器实例的限定名称。

有关此属性的更多信息,请参阅PEP 3155 的提案。

当然,由于__qualname__是在类定义期间设置的,因此当函数动态添加到类中时可能会出现误报。所以,这个答案基本上涵盖了函数是否已在类中定义的问题。

因此,没有明确的方法来检测这一点,因为在类内部定义并通过类访问的函数与类外部的函数没有区别。__qualname__(大多数情况除外)。

明智的做法是使用__qualname__作为“快速”检查来查看函数是否已在类中定义,如果是False,则回退到self使用inspect.signature函数和进行检查'self' in signature(func).parameters

你不可能涵盖所有情况,这是 Python,我几乎可以做任何我想做的事情。不过,据称我们都是同意的成年人。:)