あなたがlogging.pyというファイルにいるとしましょう。標準のログモジュールをインポートしようとすると、現在のファイルがインポートされることになります。ここから標準のログモジュールをインポートするにはどうすればよいですか。
4 に答える
から現在のディレクトリをいつでも削除できますがsys.path
、それは非常にハックであり、信頼できません。テストした後、ファイルが実行されている場合にこれが機能することがわかりました( として__main__
、しかしインポートされている場合は機能しないため、非常に信頼性が低くなります)。
あなたができる最善のことは、ファイルに std lib パッケージで使用される名前を付けないことだと思います。
imp
絶対パスでモジュールをロードするために使用できます。
import imp
help(imp.load_module)
load_module(...)
load_module(name, file, filename, (suffix, mode, type)) -> module
Load a module, given information returned by find_module().
The module name must include the full package name, if any.
私のMacでは、これを行いました:
import imp
py_logging = imp.load_module('logging', None, '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/logging', ('', '', 5))
dir(py_logging)
['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Filterer', 'Formatter', 'Handler', 'INFO', 'LogRecord', 'Logger', 'LoggerAdapter', 'Manager', 'NOTSET', 'PlaceHolder', 'RootLogger', 'StreamHandler', 'WARN', 'WARNING', '__all__', '__author__', '__builtins__', '__date__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__status__', '__version__', '_acquireLock', '_defaultFormatter', '_handlerList', '_handlers', '_levelNames', '_lock', '_loggerClass', '_releaseLock', '_srcfile', '_startTime', 'addLevelName', 'atexit', 'basicConfig', 'cStringIO', 'codecs', 'critical', 'currentframe', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'logProcesses', 'logThreads', 'makeLogRecord', 'os', 'raiseExceptions', 'root', 'setLoggerClass', 'shutdown', 'string', 'sys', 'thread', 'threading', 'time', 'traceback', 'types', 'warn', 'warning']
dir(logging)
['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Filterer', 'Formatter', 'Handler', 'INFO', 'LogRecord', 'Logger', 'LoggerAdapter', 'Manager', 'NOTSET', 'PlaceHolder', 'RootLogger', 'StreamHandler', 'WARN', 'WARNING', '__all__', '__author__', '__builtins__', '__date__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__status__', '__version__', '_acquireLock', '_defaultFormatter', '_handlerList', '_handlers', '_levelNames', '_lock', '_loggerClass', '_releaseLock', '_srcfile', '_startTime', 'addLevelName', 'atexit', 'basicConfig', 'cStringIO', 'codecs', 'critical', 'currentframe', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'logProcesses', 'logThreads', 'makeLogRecord', 'os', 'raiseExceptions', 'root', 'setLoggerClass', 'shutdown', 'string', 'sys', 'thread', 'threading', 'time', 'traceback', 'types', 'warn', 'warning']
ご覧のとおり、コンポーネントのセットは同じです。
これはあまり乾燥していないことに注意してください。つまり、使用している基本システムに基づいてログ モジュールの場所を更新する必要があります。次の方法で確認できます。
>>> import logging
>>> logging.__file__
'/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/logging/__init__.pyc'
またはimp.find_module
fp, pathname, description = imp.find_module('logging')
、カスタムlogging.py
が見つからないディレクトリで使用します...
最後の注意として、モジュールに名前を付ける理由があると確信していますが、logging.py
競合しない他のものをお勧めします。
samy.vilar からの回答には、多くの便利なオプションがあります。ただし、最も単純で直接的な答えを探している場合は、次のようになります。
import imp
import sys
f, pathname, desc = imp.find_module('logging', sys.path[1:])
logging = imp.load_module('logging', f, pathname, desc)
ここで注意すべき点がいくつかあります。
このload_module
呼び出しは、ローカル スコープでname をバインドしないという点では似ていreload(logging)
ますが、 name の下にある既存のモジュールを置き換えます。そのため、これより前に行ったことがある場合、その名前は古いモジュールではなく、新しいモジュールを参照するようになりました。そうでない場合、名前はスコープにバインドされていません。(そのため、スコープに入れるために上にあります。)import logging
logging
logging
import logging
logging
logging =
現在のディレクトリをモジュールパスに入れる '' が実際に の最初のエントリであることが実際に保証されているかどうかはわかりませんsys.path
。さらに言えば、'' または '.' を自分で sys.path に挿入することは常に可能です。したがって、偏執的になりたい場合は、次のようにすることができます。
f, pathname, desc = imp.find_module('logging', [path for path in sys.path if path and path[0] != '.'])
または、さらに偏執的になる可能性があります。たとえば、さまざまな方法で比較abspath(path)
してsys.argv[0]
、os.getcwd()
誰かがこっそりと再インポートを強制していないことを確認します。それはあなたの目標が何であるかによって異なります。
インポートされたファイルは にキャッシュされsys.modules
、同じ名前の別のモジュールをインポートしようとすると、単にキャッシュされたモジュールが返されます。競合を解決する方法はありません。
ハックとして、 の辞書エントリを削除できますがsys.modules
、それがどの程度うまく機能するかはわかりません。買い手責任負担。
del sys.modules['logging']
もちろんその後、適切なファイルがインポートされるようにパスを変更する方法を見つける必要があります。
私の全体的なアドバイスは、状況を完全に防ぎ、ファイルの名前を変更して競合がないようにすることです。