[英]Setting metaclass of wrapped class with Boost.Python
我有一个在C ++中定义的Event
类,我使用Boost向Python公开。 我的脚本应该派生自这个类,并且我想在定义新的子类时进行一些初始化。
如何设置公开的Event
类的元类,以便每当Python脚本派生自此类时,元类都可以执行所需的初始化?
我想避免在脚本中明确使用元类...
class KeyboardEvent(Event): # This is what I want
pass
class KeyboardEvent(Event, metaclass=EventMeta): # This is not a good solution
pass
编辑: 解决方案的一部分
似乎没有办法用Boost.Python设置元类。 接下来最好的事情是在定义类之后即兴创建和更改元类。 在本机Python中,更改元类的安全方法是执行此操作:
B = MetaClass(B.__name__, B.__bases__, B.__dict__)
在Boost中,它看起来像这样:
BOOST_PYTHON_MODULE(event)
{
using namespace boost::python;
using boost::python::objects::add_to_namespace;
class_<EventMetaClass> eventmeta("__EventMetaClass")
...;
class_<Event> event("Event")
...;
add_to_namespace(scope(), "Event",
eventmeta(event["__name__"], event["__bases__"], event["__dict__"]));
}
问题是我似乎找不到使用Boost.Python定义元类的方法,这就是为什么我打开了如何使用Boost.Python定义Python元类的原因? 。
如果boost没有提供从c ++开始的方法,并且它看起来没有,那么就要创建实现元类的包装类 -
它可以或多或少自动地使用一点点的自省。 假设您的boost模块名为“event” - 您应该将文件命名为_event或将其放在模块中,然后编写一个python文件 - 名为“event.py”(或模块上的__init__.py
文件)或多或少地做这个:
import _event
class eventmeta(type):
...
event_dict = globals()
for key, value in _event.__dict__.items():
if isinstance(value, type):
event_dict[key] = eventmeta(key, (value,),{})
else:
#set other module members as members of this module
event_dict[key] = value
del key, value, event_dict
Thos cpde将自动设置模块变量等于在本机“_event”模块中找到的任何名称 - 并且对于它遇到的每个类,创建一个更改元类的新类,如示例所示。
这样做可能会导致元类冲突。 如果是这样,那么通过创建适当的__getattribute__
和__setattr__
方法,方法是使新创建的类成为本机类的代理。 如果您需要这样做,请在评论中提问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.