确定方法的参数是否为“自身”

时间:2018-07-04 16:56:00

标签: python python-2.7

在问题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

2 个答案:

答案 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,则传递给函数的第一个参数将是实例,而不管其名称如何。