让我们说你在一个名为logging.py的文件中。如果您尝试导入标准日志记录模块,您最终将导入您所在的文件。如何从此处导入标准日志记录模块?
答案 0 :(得分:2)
您可以随时从sys.path
删除当前目录,但这非常hackish,而且不可靠。经过测试,我意识到这可以在文件运行时运行(如__main__
,但如果它被导入则不行,这是非常不可靠的。)
我认为你能做的最好的事情就是不要使用std lib包使用的名称来命名你的文件。
答案 1 :(得分:1)
您可以使用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
我还是会推荐一些不会发生冲突的东西。
答案 2 :(得分:1)
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
调用更像reload(logging)
而不是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()
,以确保没有人偷偷地强迫你重新导入自己。这取决于你的目标。
答案 3 :(得分:-1)
导入的文件缓存在sys.modules
中,任何导入另一个具有相同名称的模块的尝试都只会返回缓存的模块。没有办法解决冲突。
作为一个黑客,你可以删除sys.modules
中的字典条目,但我不知道它会有多好用。警告Emptor。
del sys.modules['logging']
当然,之后你必须找到一种修改路径的方法,以便导入正确的文件。
我的总体建议是完全防止这种情况,并重命名您的文件,以便没有冲突。