[英]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.