Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python3.x中检测未绑定方法的使用?_Python_Python 3.x_Metaprogramming - Fatal编程技术网

如何在Python3.x中检测未绑定方法的使用?

如何在Python3.x中检测未绑定方法的使用?,python,python-3.x,metaprogramming,Python,Python 3.x,Metaprogramming,我有一个库,它可以接受类函数,也可以接受具有特定签名的普通函数。类通常如下所示: class MyObject(object): def __init__(self, request): self.request = request def run(self): return 'OK' 函数格式如下: def my_func(request): retrn 'OK' 此选项的用法是: add_runner(MyObject, attr=

我有一个库,它可以接受类函数,也可以接受具有特定签名的普通函数。类通常如下所示:

class MyObject(object):
    def __init__(self, request):
       self.request = request

    def run(self):
        return 'OK'
函数格式如下:

def my_func(request):
    retrn 'OK'
此选项的用法是:

add_runner(MyObject, attr='run')
add_runner(my_func)
但有时人们会错误地利用这一点,并将类函数传递给我的库:

add_runner(MyObject.run)

我在Python2.x中检测到这是一个未绑定的方法,并发出一个错误来警告他们使用我的API是错误的,但在Python3.x中,我找不到任何方法来实际检测他们是否这样做了。我错过了什么?

我认为这很有效,我只是讨厌我必须检测自我


对于Python3,无界方法与函数完全等效,请参见中的讨论

检查第一个参数name==“self”可能会有问题,因为不要求方法的第一个参数为“self”。可以使用任何有效的参数名称,例如“我自己”、“这个”等

我建议use继续使用参数检查,以确保调用者提供了一个具有您期望的调用签名的函数

在python3中,可以将unbound方法正确地传递给add\u runner:

class AnotherObject:
   def run(request):
     return "OK"

add_runner(AnotherObject.run)

如果您可以假设Py27及更高版本,那么以下方法似乎可以奏效:

def是一种有效的方法: 返回boolgettermethod,'.\u self',无 在Py26中,除了im_self之外,还添加了uu self_uuu属性,以提高与Py3的兼容性。有关详细信息,请参阅

在Py2中,未绑定的方法将有一个_self__),但该值将为None。绑定方法将有一个_self __,它对应于调用它的类的实例


在Py3中,在类的实例上调用的绑定方法将定义_uself_;。相反,在类定义本身上调用的未绑定方法不会定义_self _.

是,但我要检测的是无效用法。因此,如果run是一个实例方法,即通过self绑定到类的实例,那么它是无效的,因为我不希望self传递它。如果run是一个实例方法,inspect.ismethodobjectInstance.run将返回True
class AnotherObject:
   def run(request):
     return "OK"

add_runner(AnotherObject.run)