我正在一些 C++ 库上创建一个 Python 包装器,以实现一些低级 M2M 通信。我正在使用 Riverbank 的 SIP 包装器生成器。
C++类有一个方法:
class Bar {
public:
enum Status {
...
};
void setStatus(Status s);
Status getStatus() const;
...
};
该类包含在模块 foo
中。
SIP 使用它自己的枚举类型,但出于某些原因我想使用标准库中的 Python 3.4 枚举。
我看不到任何从 Python C API 访问 Python 定义的类的机会,因此我决定修补 __init__.py
中的包装类。主要原因是我想在 C/C++/SIP 中进行肮脏的低级工作,并在 Python 中完善类(比如添加带有正常错误消息的参数验证)。
Python __init__.py
部分看起来像这样(或多或少):
from foo import Bar
class Status(IntEnum):
ONE = 1
TWO = 2
... and so on ...
Status.__module__ = 'Bar.Status'
Bar.Status = Status
Bar.status = property(...)
Bar.status
将接受并返回漂亮的 pythonic Bar.Status
枚举。
预期结果是这样的:
class Bar(object):
class Status(IntEnum):
...
...
我想知道这种方法是否有任何问题,尤其是在导入时修补对象。
最佳答案
我用其他似乎没问题的方式解决了这个问题。
让我们考虑一个包含两个类的 C++ 库:
- 福
- FooFactory
Wrapper 库包含包libfoo
(在Python C API 中创建)和pythonic 包foo
(在普通python 中创建)。我们不直接访问libfoo
包,而是导入foo
。
打包foo
的__init__.py
:
from libfoo import Foo, FooFactory
# both are naked wrappers with ugly API derived from C++
# I defined some pythonic sugar that makes them nice to use
class FooPythonicGoodies(object):
# add pythonic goodies here
def quack(self):
pass
# Merge them
Foo.__bases__ = Foo.__bases__ + (FooPythonicGoodies,)
现在,当我在源代码的任何地方执行此操作时:
from foo import Foo, FooFactory
a = Foo()
a.quack()
# Factory is a C++ wrapped class that returns wrapped foo
# objects WITH FooPythonicGoodies!
factory = FooFactory()
b = factory.create_foo()
b.quack() # that works too!
这样我就可以使用 pythonic API 糖来完善非 pythonic C++ 类。
关于python - 包裹在 SIP 中的 C++ 类在 Python 中修补,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23460396/