【问题标题】:Getting argument list in a Boost:Python function在 Boost:Python 函数中获取参数列表
【发布时间】:2013-05-10 12:05:20
【问题描述】:

在 CPython 中,我们可以通过以下方法获取函数的参数列表。 函数名是'aMethod'

import inspect
inspect.getargspec(aMethod)

aMethod.func_code.co_varnames

如何为 Boost:Python 函数实现相同的功能?当我使用这些方法时,我得到以下错误。

对于第一种方法 TypeError: 不是 Python 函数

对于第二种方法 AttributeError: 'aMethod' 对象没有属性 'func_code'

【问题讨论】:

    标签: python boost python-2.7 boost-python cpython


    【解决方案1】:

    访问boost::python::object 上的Python 属性时,请使用attr 成员函数。例如:

    aMethod.func_code.co_varnames
    

    会变成

    aMethod.attr("func_code").attr("co_varnames")
    

    这是一个完整的例子。

    #include <iostream>
    #include <vector>
    
    #include <boost/foreach.hpp>
    #include <boost/python.hpp>
    #include <boost/python/stl_iterator.hpp>
    
    void print_varnames(boost::python::object fn)
    {
      namespace python = boost::python;
      typedef python::stl_input_iterator<std::string> iterator;
    
      std::vector<std::string> var_names(
        iterator(fn.attr("func_code").attr("co_varnames")),
        iterator());
    
      BOOST_FOREACH(const std::string& varname, var_names)
        std::cout << varname << std::endl;
    }
    
    BOOST_PYTHON_MODULE(example)
    {
      def("print_varnames", &print_varnames);
    }
    

    用法:

    >>> def test1(a,b,c): pass
    ... 
    >>> def test2(spam, eggs): pass
    ... 
    >>> def test3(): pass
    ... 
    >>> from example import print_varnames
    >>> print_varnames(test1)
    a
    b
    c
    >>> print_varnames(test2)
    spam
    eggs
    >>> print_varnames(test3)
    >>> 
    

    【讨论】:

    • 错误 C2039:“stl_input_iterator”:不是“boost::python”的成员。我在构建时收到此错误。我在 Windows 7 32 位、Python 2.7 和 Boost 1.47 上使用 Visual Studio 2010。
    • 在导入 stl_iterator 后它可以工作,但在使用该方法获取参数列表时给出相同的错误。
    • 好的。我想到了。我用来获取参数的函数存在问题。仅当在命令提示符下运行 Python 时,此问题才有效。但无论如何,它现在可以工作了:D。谢谢
    • @maheshakya:我已经进行了编辑,因为它没有任何危害。截至 2 年前,主干 (r72746) 上的 convenience header file 包括 stl_iterator。但是,它似乎没有合并到发布分支中。
    【解决方案2】:

    小心:这种方法将打印出函数中的所有变量,而不仅仅是其参数。也就是说:

    def test4(a, b):
        c = a + b
    
    >>> test4.__code__.co_varnames
    ('a', 'b', 'c')
    

    如果你真的只需要函数参数,只需使用inspect 模块:

    // given f as callable boost::python::object
    auto inspect = python::import("inspect");
    auto argspec = inspect.attr("getargspec")(f);
    // returns args in argspec[0] (and varargs in [1], keywords in [2], and defaults in [3]).
    

    【讨论】:

      猜你喜欢
      • 2016-09-07
      • 1970-01-01
      • 2012-09-29
      • 2020-04-08
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      相关资源
      最近更新 更多