3

我正在使用 swig 为 C++ 库生成 python 包装器。我倾向于使用 ipython 以交互方式使用生成的 python 模块。

假设我有以下 C++ 类:

class test
{
    int num;
    int foo();
};

Swig 用一个 python 类包装了这个类:

class test:
    def foo():...
    __swig_getmethods__["num"] = ...
    __swig_setmethods__["num"] = ...
    .
    .
    .

与 ipython 交互使用时。我注意到选项卡完成将成功找到“foo”,但不是“num”。

经过一番挖掘,我看到 ipython 使用“dir”方法进行选项卡补全。swig 生成非函数类成员的方式是通过实现__setattr__and __getattr__。他们所做的只是检查__swig_set/getmethods__字典并返回值(如果找到)。这就是为什么在尝试时不返回像“num”这样的成员的原因dir(test)

__dir__理想情况下,如果 swig 可以为它的每个类实现 , 那就太好了。这样的东西可以添加到每个 swig 包装类中:

# Merge the two method dictionaries, and get the keys
__swig_dir__ = dict(__swig_getmethods__.items() + __swig_setmethods__.items()).keys()
# Implement __dir__() to return it plus all of the other members
def __dir__(self):
    return __dict__.keys() + __swig_dir__ 

我的问题:

  1. 是否有一种简单的方法可以让 dir() 函数也返回非函数成员?
  2. 如果 1 的答案是否定的,是否有一种简单的方法可以在 swig 生成的每个 python 类中添加上述代码?

我知道这是一件小事,但在我看来,制表符补全对生产力有非常积极的影响。

谢谢

4

1 回答 1

2

IPython 将 dir 包装在 IPython/core/completer.py 内的新函数 dir2 中

所以你可以尝试重新定义dir2。就像是:

import IPython.core.completer
old_dir = IPython.core.completer.dir2

def my_dir(obj):
    methods = old_dir(obj)
    #merge your swig methods in
    return methods

IPython.core.completer.dir2 = my_dir
于 2012-09-09T23:54:55.877 回答