2012-01-29 32 views
14

API C C có đối tượng PyObject *PyType_Type, tương đương với type trong trình thông dịch. Nếu tôi muốn xác định một metaclass trong C + +, làm thế nào tôi có thể thiết lập type là một trong những căn cứ của nó trong Boost.Python? Ngoài ra, những thứ khác tôi nên xem xét khi xác định một metaclass Python trong C + +?Làm thế nào để xác định một metaclass Python với Boost.Python?

Sẽ rất lý tưởng nếu có giải pháp Boost.Python cho điều này. Nếu không, một giải pháp sử dụng Python C API (hoặc kết hợp Boost và C API) cũng tốt. Kể từ khi các lớp khác của tôi được tiếp xúc với Boost, tôi muốn rời SWIG như một phương sách cuối cùng.

Lưu ý: Đây thực sự là một phần của vấn đề lớn hơn mà tôi đang cố giải quyết, mà tôi đã hỏi về số Setting metaclass of wrapped class with Boost.Python nếu bạn quan tâm.

+0

Bạn chỉ đang tìm giải pháp Boost.Python? Tôi nghĩ rằng tôi có thể giải quyết điều này với SWIG :) – Flexo

+0

@awoodland Boost.Python là thích hợp hơn, nhưng tôi không phản đối SWIG. –

+0

Ok, nếu bạn không nhận được câu trả lời hay, câu trả lời của tôi sẽ ping tôi để nhắc tôi với một @ khác và tôi sẽ xem xét thực hiện nó với SWIG. – Flexo

Trả lời

4

Được rồi, cảm giác này giống như hack nhưng có vẻ như nó hoạt động.

#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__"); 
} 

sau đó trong python

from meta import Meta 

class Test(object): 
    __metaclass__ = Meta 

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

tôi đã cố gắng một số thứ khác mà không sử dụng tăng :: Hệ thống python :: đối tượng nhưng không thể có được bất cứ điều gì mà làm việc như thế này từ phía python .

Mặc dù nói đúng cách đây không phải là một metaclass vì nó không kế thừa từ kiểu, nhưng nó hoạt động như một vì kiểu được sử dụng trực tiếp trong hàm newClass khi gọi mới. Nếu thats không phải là một vấn đề thì nó có thể là khôn ngoan để thay đổi nó từ

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

để

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

hoặc một cái gì đó tương tự để Tăng :: Python :: lớp được sử dụng thay vì nhập.

+0

Tôi sẽ dùng thử. Nó rất có thể sẽ không làm việc với Python 3 (đó là phiên bản tôi muốn sử dụng), nhưng tôi đoán tôi sẽ hạ cấp nếu tôi phải. –

+0

nếu bạn chưa thực hiện xong, bạn có thể yêu cầu trên http://boost.2283326.n4.nabble.com/Python-c-sig-f2696818.html – babak

+0

Tôi đã trao cho bạn tiền thưởng vì câu trả lời này khá tốt, nhưng tôi sẽ không chấp nhận nó. Tôi vẫn đang tìm một giải pháp mà sẽ làm việc cho Python 3 là tốt. Nếu tôi không tìm thấy thì tôi sẽ chấp nhận câu trả lời này. –

Các vấn đề liên quan