在问题How can I find the number of arguments of a Python function?中,给出了显示如何使用inspect.getfullargspec
获取功能信息的代码。但是,是否有任何方法可以验证该函数的参数之一是否为self
?在Python 3中,inspect.signature
自动为您删除self
参数。通过某种方式检查给定函数的第一个参数是否是对该方法对象的引用,是否有可能完成Python 2的相同工作?
例如,函数step
中的第一个参数从技术上讲是self
,即使有人决定变邪恶并将self
重命名为what
。
class TestNode(object):
def __init__(what, bias=0):
what.bias = bias
def update(what, t, x):
return t / x * what.bias
但是,功能lambda self: self+1
中的第一个参数尽管有人邪恶并命名了参数self
,但实际上并不是Python对象中使用的self
。
答案 0 :(得分:2)
如果我们从参数检查中退后一步,并且将此问题视为确定函数是否为方法的问题。我们可以使用inspect.ismethod
函数来做到这一点:
>>> import inspect
>>> class Foo:
... def bar(self):
... pass
...
>>> inspect.ismethod(Foo().bar)
True
如果函数是绑定方法,我们可以放心地假定,此方法的第一个传递参数为self
。
请注意,在Python 2.X中,此方法将对未绑定的方法(例如Foo.bar
)返回True,而在3.X中,仅当方法绑定时,它才会返回True。
我们可以使用getmembers进一步迈出这一步,并实际确定此绑定方法的self
值是什么:
>>> dict(inspect.getmembers(Foo()))["bar"].__self__
<__main__.Foo object at 0x7f601eb50a58>
哪个返回此Foo()
方法绑定到的bar
实例。在Python 2.X中,如果实例是未绑定的,则__self__
将是None
,这是区分绑定方法和未绑定方法的方式。
答案 1 :(得分:1)
self
不是一个特殊的参数。名称self
没什么特别的-与其他名称一样,这是一个正常的论点,它被命名为self
的唯一原因是程序员之间的约定。
您无法将self
自变量与其他自变量区分开,因为根本没有区别!
您可以做的是检查该函数是否是类的成员-然后它成为一个方法并自动将实例作为第一个参数获取-这可以通过元类描述符完成参见here in the documentation。
如果inspect.ismethod()
返回True
,则传递给函数的第一个参数将是实例,而不管其名称如何。