【问题标题】:Can't get argspec for Python callables?无法获取 Python 可调用对象的 argspec?
【发布时间】:2010-10-22 17:39:52
【问题描述】:

我正在使用 Python 可调用对象。基本上你可以定义一个 python 类并实现__call__ 方法来使这个类的实例可调用。例如,

class AwesomeFunction(object):
    def __call__(self, a, b):
        return a+b

Module inspect 有一个函数 getargspec,它给你一个函数的参数说明。但是,似乎我不能在可调用对象上使用它:

fn = AwesomeFunction()
import inspect
inspect.getargspec(fn)

不幸的是,我收到了一个 TypeError:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/inspect.py", line 803, in getargspec
    raise TypeError('arg is not a Python function')
TypeError: arg is not a Python function

我认为很遗憾你不能将任何可调用对象视为函数,除非我在这里做错了什么?

【问题讨论】:

  • 感谢您提醒我一种较少使用和理解的魔术方法,__call__

标签: python reflection inspection


【解决方案1】:

如果您需要此功能,编写一个包装函数来检查fn 是否具有属性__call__,如果有,则将其__call__ 函数传递给getargspec。

【讨论】:

    【解决方案2】:

    如果您查看 svn.python.org 上 inspect 模块代码中的 getargspec 定义。你会看到它调用了isfunction,它自己调用了:

    isinstance(object, types.FunctionType)
    

    因为,您的 AwesomeFunction 显然不是 types.FunctionType 的实例,所以它失败了。

    如果你想让它工作,你应该尝试以下方法:

    inspect.getargspec(fn.__call__)
    

    【讨论】:

    • 我知道它需要一个函数类型。我只是在感叹 Python 没有以统一函数和对象的方式进行设计。
    • 这主要是因为 Python 并不是一门极其面向对象的语言(Java 是我最好的例子)。在 Java 中,从字面上看,一切都是对象,以至于可运行源的最小单元是类。在 Python 中,由于避开了这样的范式,是的,缺少一些功能,但通常更清晰。
    • @EnToutCas:写一个提案/补丁。可能 A) 被接受,或 B) 被击落,理由是说明为什么这是一个坏主意。
    • @Nick,好主意。无需检查函数类型,inspect.getargspec 只需检查 arg 是否具有属性 __call__。虽然我不认为这会被接受为补丁......
    【解决方案3】:

    __call__ 定义了可以被类实例调用的东西。你没有给 getargspec 一个有效的函数,因为你正在向它传递一个类实例。

    __init__call__ 的区别是这样的:

    fn = AwesomeFunction() # call to __init__
    fn(1, 2) # call to __call__
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多