2017-03-13 3 views
10

Ich habe eine C-Erweiterung, die Umgebungsvariablen während der statischen Initialisierung lädt. Ich muss in der Lage sein, diese Werte zu ändern und das Modul neu zu laden (ich kann die Tatsache nicht ändern, dass sie statisch geladen werden). Ich habe versucht Einstellung os.environ, aber es scheint nicht, wie in importlib eine env Option zu sein für subprocess.callÄndern der Umgebungsvariablen vor dem Importlib.Reload

Hier ein Beispiel: Angenommen, ich habe ein Modul definiert als

#include <boost/python.hpp> 
#include <cstdlib> 
#include <string> 
std::string get() { 
    return ::getenv("HOME"); 
} 

BOOST_PYTHON_MODULE(sample) { 
    boost::python::def("get", &get); 
} 

folgt Und ich habe Python-Code:

import importlib, os 
import sample as s 
print(s.get()) # prints /home/username 

# do something like 
# os.environ['HOME'] = 'foo' 
importlib.reload(s) 
print(s.get()) # I would like this to print 'foo' 

mit anderen Worten, was ich anstelle von os.environ['HOME'] = 'foo' tun kann die Umgebungsvariable können in c-Modul ändern?

HINWEIS: Ich kann setenv nicht verwenden, da die Variablen statisch geladen werden und ich nicht alle Dinge neu initialisieren kann, die von ihnen abhängen.

Antwort

4

Wenn ich mich nicht irre, der Grund, warum das nicht funktioniert, ist nicht, weil die Umgebung nicht geändert wird, sondern weil, wenn Sie tun importlib.reload(s)the c module is not actually re-initialized.

Was Sie tun können, ist Ihre Anrufe an s in einem anderen Prozess, und wann immer Sie es neu laden müssen erstellen Sie einen neuen Prozess.

+0

Sie haben Recht, dass die C-Module nicht neu initialisiert werden. Ich möchte lieber keine neuen Prozesse erstellen, da ich das c-Modul überhaupt erst geschaffen habe, um das zu vermeiden. – JRG

+0

@JRG wenn ich darf, was versuchst du mit dieser c-extension zu erreichen? Offensichtlich versuchen Sie nicht, Umgebungsvariablen zu lesen, denn wenn das der Fall wäre, könnten Sie dies auf der Python-Seite tun und keine c-Erweiterung verwenden. Wenn es ein größeres Ziel gibt, dann könntest du vielleicht Umgebungsvariablen für die Kommunikation vermeiden und etwas anderes verwenden. –

0

Vielleicht können Sie etwas mit Py_Finalize und Py_Initialize in Ihrer oder einer zweiten c-Erweiterung tun, die Ihr Modul neu laden ersetzen wird? Aber es ist vielleicht ein Overkill ...?

+0

Es ist ein guter Gedanke, aber dann müsste ich C-Bindings für meinen C++ Code erstellen, um in den zweiten .so zu exportieren. – JRG

Verwandte Themen