私は pypreprocessor に取り組んでいます。これは、cスタイルのディレクティブを受け取るプリプロセッサであり、従来のプリプロセッサのように機能させることができました(自己消費型で、後処理コードをその場で実行します) fly)ライブラリのインポートを壊すことを除いて。
問題は、プリプロセッサがファイルを実行して処理し、一時ファイルに出力し、一時ファイルをexec()することです。インポートされたライブラリは実行されないため、少し異なる方法で処理する必要があります。ライブラリはロードされ、呼び出し元モジュールからアクセスできるようになります。
私ができる必要があるのは:インポートを中断し(インポートの途中でプリプロセッサーが実行されているため)、後処理されたコードをtempModuleとしてロードし、元のインポートをtempModuleに置き換えて、呼び出しスクリプトをだましてtempModuleが元のモジュールであると信じ込むためのインポート。
私はあらゆる場所を検索してきましたが、解決策はありません。
このスタックオーバーフローの質問は、これまでに答えを提供するのに最も近いものです。 Pythonでの名前空間のオーバーライド
これが私が持っているものです。
# Remove the bytecode file created by the first import
os.remove(moduleName + '.pyc')
# Remove the first import
del sys.modules[moduleName]
# Import the postprocessed module
tmpModule = __import__(tmpModuleName)
# Set first module's reference to point to the preprocessed module
sys.modules[moduleName] = tmpModule
moduleNameは元のモジュールの名前で、tmpModuleNameは後処理されたコードファイルの名前です。
奇妙なことに、このソリューションは、最初のモジュールが正常にロードされたかのように、完全に正常に実行されます。最後の行を削除しない限り、モジュールが見つからないというエラーが発生します。
うまくいけば、スタックオーバーフローの誰かが私よりもインポートについて多くのことを知っていると思います。
注:私はソリューションを授与します。または、これがPythonで不可能な場合のみです。これが不可能でない理由の最も詳細な説明
更新:興味のある方のために、ここに作業コードを示します。
if imp.lock_held() is True:
del sys.modules[moduleName]
sys.modules[tmpModuleName] = __import__(tmpModuleName)
sys.modules[moduleName] = __import__(tmpModuleName)
'imp.lock_held'パーツは、モジュールがライブラリとしてロードされているかどうかを検出します。次の行は残りを行います。
これはあなたの質問に答えますか? 2番目のインポートでうまくいきます。
Mod_1.py
def test_function():
print "Test Function -- Mod 1"
Mod_2.py
def test_function():
print "Test Function -- Mod 2"
Test.py
#!/usr/bin/python
import sys
import Mod_1
Mod_1.test_function()
del sys.modules['Mod_1']
sys.modules['Mod_1'] = __import__('Mod_2')
import Mod_1
Mod_1.test_function()
異なるインポート動作を定義したり、インポートプロセスを完全に覆したりするには、インポートフックを記述する必要があります。 PEP 302 を参照してください。
例えば、
import sys
class MyImporter(object):
def find_module(self, module_name, package_path):
# Return a loader
return self
def load_module(self, module_name):
# Return a module
return self
sys.meta_path.append(MyImporter())
import now_you_can_import_any_name
print now_you_can_import_any_name
それは出力します:
<__main__.MyImporter object at 0x009F85F0>
したがって、基本的には新しいモジュール(任意のオブジェクトにすることができます)、この場合はそれ自体を返します。 xxx
のインポート時にprocesse_xxx
を返すことで、インポートの動作を変更するために使用できます。
IMO: Python はプリプロセッサを必要としません。あなたが達成していることは何でも、Python自体それ自体が非常に動的な性質により、たとえば、デバッグ例の場合、ファイルの先頭にあることで何が悪いのか
debug = 1
以降
if debug:
print "wow"
?