2015-03-12 5 views
5

Ich versuche über Boost Python ein Paket zu erstellen, das mehrere Module enthalten wird.Boost Python mehrere Module in einem gemeinsamen Objekt

Die Argumentation ist, dass wir eine sehr große API bereitstellen möchten, und es ist sinnvoll, es in verschiedenen Modulen für die Benutzerfreundlichkeit zu gruppieren und Python-Speichernutzung zu erhalten. Auf der anderen Seite sind wir (aus Gründen über den Umfang dieser Frage diese in ein einziges gemeinsamen Objekt zu kompilieren)

So erzeuge ich mit Boost Python gezwungen ein Paket, das mehr Module, wie folgt exportiert:

void exportClass1() 
{ 
    namespace bp = boost::python; 
    // map the IO namespace to a sub-module 
    // make "from myPackage.class1 import <whatever>" work 
    bp::object class1Module(bp::handle<>(bp::borrowed(PyImport_AddModule("myPackage.class1")))); 
    // make "from mypackage import class1" work 
    bp::scope().attr("class1") = class1Module; 
    // set the current scope to the new sub-module 
    bp::scope io_scope = class1Module; 

    // export stuff in the class1 namespace 

    class_<class1 >("class1", init<>()) 
    . 
    . CLASS SPECIFICS GO HERE 
    . 

    Other class of module class1 go here as well 
} 

BOOST_PYTHON_MODULE(myPackage) 
{ 
    namespace bp = boost::python; 

    // specify that this module is actually a package 
    bp::object package = bp::scope(); 
    package.attr("__path__") = "myPackage"; 

    exportClass1(); 
    exportClass2(); 
    . 
    . 
    . 

} 

Dieser Code funktioniert.

Das Hauptproblem ist Speicherverbrauch. Die gesamte exponierte API ist sehr groß so lädt das gesamte Paket etwa 65 MB RAM, nur für alle Erklärungen. (bevor der Paketbenutzer irgendetwas zu tun begann)

Dies ist natürlich inakzeptabel. (Vorausgesetzt, dass ein einzelnes Modul Laden sollte vielleicht 1-3MB RAM verbrauchen)

Wenn in Python, wenn ich rufe:

from myPackage.myModule import * 

ODER

from myPackage.myModule import someClass 

Der Speicherverbrauch immidietly zu 65MB Raketen .

Nach jedem des Import zu tun, wenn ich rufe: sys.modules ich alle Klassen in meinem Paket sehen als „bekannt“ Allerdings, wenn ich laufe:

from myPackage.myModule import class1 
c = class2() 

ich eine Fehlermeldung erhalten:

NameError: name 'class2' is not defined

so scheint es, ich das schlimmste von zwei Welten, auf die man die Hände ich Speicher verbrauchen, als ob ich alles aus meinem Paket importiert, auf der anderen Seite habe ich die Klassen nicht wirklich importiert bekommen.

Irgendwelche Ideen, wie man das löst, so dass, wenn ich ein bestimmtes Modul importiere, es nur importiert wird, und nicht alle Paketdaten in den Pythonspeicher gelesen werden. (was beides Zeit braucht und viel wertvollen Speicher verbraucht)

Antwort

2

Das war also viel einfacher als ich angenommen hatte.

Der obige Code korrekt ist auch die Anrufe in Form von für die Herstellung von:

from myPackage.myModule import class1 
c = class2() 

Was dies aus hindert richtig die Wege System wurden ausgeführt. Das freigegebene Objekt wurde nicht an einem Speicherort des Python-Pfads platziert und hatte keine __init__.py in dem Ordner, in dem es platziert wurde.

Sobald das gemeinsame Objekt in den richtigen Site-Packages-Ordner gelegt wurde, funktioniert natürlich __init__.py das obige Beispiel funktioniert ordnungsgemäß.

Verwandte Themen