def is_unbound_method(func):
pass
def foo(): pass
class MyClass(object):
def bar(self): pass
我可以在is_unbound_method
的身体中放置什么
is_unbound_method(foo) == False
is_unbound_method(MyClass().bar) == False
is_unbound_method(MyClass.bar) == True
...
答案 0 :(得分:8)
未绑定的方法将__self__
设置为None
:
def is_unbound_method(func):
return getattr(func, '__self__', 'sentinel') is None
演示:
>>> foo.__self__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute '__self__'
>>> is_unbound_method(foo)
False
>>> MyClass.bar.__self__
>>> is_unbound_method(MyClass.bar)
True
>>> MyClass().bar.__self__
<__main__.MyClass object at 0x106c64a50>
>>> is_unbound_method(MyClass().bar)
False
该属性也可用.im_self
,但__self__
是向前兼容的。
请注意,在Python 3中,未绑定的方法已经消失;访问MyClass.bar
返回函数对象。因此,上述函数将始终返回False
。
请参阅用户定义的方法部分中的Datamodel documentation:
特殊只读属性:
im_self
是类实例对象,im_func
是函数对象[...]
在版本2.6中更改:对于Python 3向前兼容性,
im_func
也可用作__func__
,im_self
可用作__self__
。[...]
通过从类中检索用户定义的函数对象来创建用户定义的方法对象时,其
im_self
属性为None,并且方法对象被称为未绑定。
答案 1 :(得分:0)
这就是我提出的......根据正确答案中的评论,仅对2.x有效
def is_unbound_method(func):
"""Test if ``func`` is an unbound method.
>>> def f(): pass
>>> class MyClass(object):
... def f(self): pass
>>> is_unbound_method(f)
False
>>> is_unbound_method(MyClass().f)
False
>>> is_unbound_method(MyClass.f)
True
"""
return getattr(func, 'im_self', False) is None
答案 2 :(得分:0)
在Python 3中,没有可靠的方法可以仅通过函数对象来确定(因为类中定义的任何函数都与其他函数一样)。
也许次优的方法是检查签名并检查self
作为第一个参数:
import inspect
def is_unbound_method(obj):
signature = inspect.signature(obj)
if not signature.parameters:
return False
return next(iter(signature.parameters), None) == "self"
但是,当然,这取决于第一个参数被命名为self
(和在其他函数上 not 而不是使用self
作为第一个参数),这只是一个约定。
如果您已经知道对象是在类中定义的,那么更好的方法可能是检查它是不是classmethod
或staticmethod
的可调用对象: / p>
import inspect
def is_unbound_method_from(cls, obj):
return bool(
callable(obj)
and not isinstance(obj, (classmethod, staticmethod))
and inspect.getmembers(cls, lambda m: m is obj)
)
您应该从您认为最不可能的可能性中重新排序以上连接中的子句(以避免不必要的计算)。