2012-01-29 2 views
14

API Python C имеет объект PyObject *PyType_Type, который эквивалентен type в интерпретаторе. Если я хочу определить метакласс в C++, как установить type в качестве одной из его баз в Boost.Python? Кроме того, что еще нужно учитывать при определении метакласса Python в C++?Как определить метакласс Python с помощью Boost.Python?

Было бы идеально, если бы это было решение Boost.Python. Если нет, то решение, использующее API Python C (или комбинацию Boost и C API), также хорошо. Поскольку мои другие классы подвергаются воздействию Boost, я предпочел бы оставить SWIG в качестве последнего средства.

Примечание: На самом деле это часть более сложной проблемы, которую я пытаюсь решить, о которой я просил в Setting metaclass of wrapped class with Boost.Python, если вам интересно.

+0

Вы ищете только решения Boost.Python? Я думаю, что я могу решить это с помощью SWIG :) – Flexo

+0

@awoodland Boost.Python предпочтительнее, но я не против SWIG. –

+0

Хорошо, если вы не получите хороший ответ Boost.Python, пингуйте мне, чтобы напомнить мне еще один, и я посмотрю на это с помощью SWIG. – Flexo

ответ

4

Хорошо, это похоже на взлом, но, похоже, он работает.

#include <boost/python.hpp> 

class Meta 
{ 
public: 
    static boost::python::object 
    newClass(boost::python::object cls, std::string name, boost::python::tuple bases, boost::python::dict attrs) 
    { 
     attrs["foo"] = "bar"; 
     boost::python::object types = boost::python::import("types"); 
     boost::python::object type = types.attr("TypeType"); 
     return type.attr("__new__")(type, name, bases, attrs); 
    } 
}; 

BOOST_PYTHON_MODULE(meta) 
{ 
    boost::python::class_<Meta>("Meta") 
    .def("__new__", &Meta::newClass) 
    .staticmethod("__new__"); 
} 

затем в питона

from meta import Meta 

class Test(object): 
    __metaclass__ = Meta 

print Test, Test.foo 
<class '__main__.Test'> bar 

я попробовал некоторые другие вещи, которые не используют системы наддува :: питона :: объект, но не могли бы получить что-нибудь, что работал так со стороны питона ,

Хотя, строго говоря, это не метакласс, так как он не наследует от типа, но он ведет себя как один, потому что тип используется непосредственно в функции newClass при вызове new. Если это еще не проблема, то это может быть целесообразно, чтобы изменить его с

return type.attr("__new__")(type, name, bases, attrs); 

в

return type.attr("__new__")(cls.attr("__class__"), name, bases, attrs); 

или что-то подобное, так Повысьте :: Python :: класс используется вместо типа.

+0

Я попробую. Скорее всего, он не будет работать с Python 3 (это версия, которую я хотел бы использовать), но я думаю, что буду понижаться, если придется. –

+0

, если вы уже сделали это уже можно было бы спросить на http://boost.2283326.n4.nabble.com/Python-c-sig-f2696818.html – babak

+0

Я наградил вас щедростью, потому что этот ответ довольно хорош, но я пока не согласятся. Я все еще ищу решение, которое будет работать и для Python 3. Если я не найду, я приму этот ответ. –

Смежные вопросы