如何判断Python中类实例定义了哪个函数?

0 投票
3 回答
672 浏览
提问于 2025-04-15 18:10

我想知道一个函数是否在某个类的实例中被定义了。

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中进行这种“鸭子类型检查”的正确方法。这种方法比以前的方式(比如使用内置的callableoperator.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 这个模块:

撰写回答