如何判断Python中类实例定义了哪个函数?
我想知道一个函数是否在某个类的实例中被定义了。
class c(object):
def func(self): pass
cc = c()
>>> is_function_defined_for_instance(cc,'func')
True
>>> is_function_defined_for_instance(cc,'cnuf')
False
我对这个函数的最简洁的尝试是:
def is_function_defined_for_instance(instance,function):
return callable(getattr(instance,function,None))
# returns True iff function is defined for class of instance (not super classes)
def is_function_defined_for_instance(instance,function):
return bool(instance.__class__.__dict__.get(function))
有没有什么内置的方法或者更好的方式来实现我想要的功能呢?
3 个回答
0
如果这个方法缺失的话,你能不能抛出一种自定义的异常?(我之前是用Ruby的 :))
3
在Python 2.6或更高版本中,推荐的做法是:
import collections
def is_func(instance, func):
return isinstance(getattr(instance, func, None), collections.Callable)
在collections
模块中,有新的抽象基类(ABCs),这是在Python 2.6及以上版本和3.x中进行这种“鸭子类型检查”的正确方法。这种方法比以前的方式(比如使用内置的callable
、operator.isCallable
,或者检查特定的特殊方法如__call__
)要优雅得多,更统一,也更能适应未来的发展。因为isinstance
现在可以被重载,所以可以让ABCs来处理重载和检查,封装那些最有效的底层方法!
这种新方法的优雅和优势在于,如果你需要让你的代码在旧版和新版Python之间可移植,我建议把你需要的“鸭子类型测试”封装在一个模块中,根据sys.version
来定义它的功能——在2.6或更高版本中使用isinstance(x, collections.Y)
,而在2.5或更低版本中使用旧的方法,比如hasattr(x, '__somespecialmethod__')
或callable(x)
。
最重要的是,通常来说,不要让你的新应用代码被旧的、低效的方法污染。如果向后兼容的要求迫使你的系统中有一些“垃圾”(为了能在旧版Python上运行),至少要把这些垃圾好好隐藏在自己的“隔间”里(将来如果你的应用部署条件允许,你可以轻松地把它们清理掉!)。
2
>>> def is_func(instance, func):
test = getattr(instance, func, None)
if test and hasattr(test, '__call__'):
return True
>>> is_func('', 'len')
>>> is_func({}, 'fromkeys')
True
>>> import inspect
>>> test = getattr(cc, 'func', None)
>>> inspect.ismethod(test)
True
或者你可以使用 inspect
这个模块: