2014-12-27 29 views
0

我有一个库,可以采取类功能或具有特定签名的正常功能。一类通常是这样的:如何在Python 3.x中检测未绑定方法的用法?

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) 

但有时人利用这个错误并通过class功能到我的书架:

add_runner(MyObject.run) 

我已经在Python 2.x中检测到这是一个未绑定的方法,并提出错误提醒他们他们正在使用我的API错误,但在Python 3.x中我找不到任何方法来真正检测到他们做错了。我错过了什么?

回答

0

我觉得这工作得很好,我只是恨我必须检测self

def _is_unbound(fn): 
    """ 
    This consistently verifies that the callable is bound to a 
    class. 
    """ 
    spec = inspect.getargspec(fn) 
    has_self = len(spec.args) > 0 and spec.args[0] == 'self' 
    is_bound = getattr(fn, im_self, None) is not None 

    if not is_bound: 
     if PY3 and inspect.isfunction(fn) and has_self: 
      return True 
     elif inspect.ismethod(fn): 
      return True 

    return False 
0

与Python 3,无限的方法是完全等价的功能(见Get defining class of unbound method object in Python 3讨论)

检查第一参数名称=='self'可能有问题,因为没有要求方法的第一个参数为'self'。任何有效的参数名称都可以使用(例如'我','this'等)。

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

在python3有可能未绑定的方法正确传递给add_runner:

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

add_runner(AnotherObject.run) 
+0

是的,但我想检测无效使用。所以如果'run'是一个实例方法(即通过'self'绑定到类的一个实例),那么它是无效的,因为我不想让自己通过它 – sontek

+0

如果'run'是一个实例方法,'inspect.ismethod(objectInstance.run)'会返回'True' – levis501

相关问题