如何加载给定完整路径的Python模块?
请注意,文件可以位于文件系统中用户具有访问权限的任何位置。
另请参阅:如何导入以字符串形式命名的模块?
如何加载给定完整路径的Python模块?
请注意,文件可以位于文件系统中用户具有访问权限的任何位置。
另请参阅:如何导入以字符串形式命名的模块?
当前回答
听起来您不想专门导入配置文件(这会带来很多副作用和额外的复杂性)。您只需要运行它,并能够访问生成的命名空间。标准库以runpy.run_path的形式专门提供了一个API:
from runpy import run_path
settings = run_path("/path/to/file.py")
该接口在Python 2.7和Python 3.2+中可用。
其他回答
在运行时导入包模块(Python配方)
http://code.activestate.com/recipes/223972/
###################
## #
## classloader.py #
## #
###################
import sys, types
def _get_mod(modulePath):
try:
aMod = sys.modules[modulePath]
if not isinstance(aMod, types.ModuleType):
raise KeyError
except KeyError:
# The last [''] is very important!
aMod = __import__(modulePath, globals(), locals(), [''])
sys.modules[modulePath] = aMod
return aMod
def _get_func(fullFuncName):
"""Retrieve a function object from a full dotted-package name."""
# Parse out the path, module, and function
lastDot = fullFuncName.rfind(u".")
funcName = fullFuncName[lastDot + 1:]
modPath = fullFuncName[:lastDot]
aMod = _get_mod(modPath)
aFunc = getattr(aMod, funcName)
# Assert that the function is a *callable* attribute.
assert callable(aFunc), u"%s is not callable." % fullFuncName
# Return a reference to the function itself,
# not the results of the function.
return aFunc
def _get_class(fullClassName, parentClass=None):
"""Load a module and retrieve a class (NOT an instance).
If the parentClass is supplied, className must be of parentClass
or a subclass of parentClass (or None is returned).
"""
aClass = _get_func(fullClassName)
# Assert that the class is a subclass of parentClass.
if parentClass is not None:
if not issubclass(aClass, parentClass):
raise TypeError(u"%s is not a subclass of %s" %
(fullClassName, parentClass))
# Return a reference to the class itself, not an instantiated object.
return aClass
######################
## Usage ##
######################
class StorageManager: pass
class StorageManagerMySQL(StorageManager): pass
def storage_object(aFullClassName, allOptions={}):
aStoreClass = _get_class(aFullClassName, StorageManager)
return aStoreClass(allOptions)
这将允许在3.4中导入编译的(pyd)Python模块:
import sys
import importlib.machinery
def load_module(name, filename):
# If the Loader finds the module name in this list it will use
# module_name.__file__ instead so we need to delete it here
if name in sys.modules:
del sys.modules[name]
loader = importlib.machinery.ExtensionFileLoader(name, filename)
module = loader.load_module()
locals()[name] = module
globals()[name] = module
load_module('something', r'C:\Path\To\something.pyd')
something.do_something()
创建Python模块test.py:
import sys
sys.path.append("<project-path>/lib/")
from tes1 import Client1
from tes2 import Client2
import tes3
创建Python模块test_check.py:
from test import Client1
from test import Client2
from test import test3
我们可以从模块导入导入的模块。
为了补充塞巴斯蒂安·里托的回答:至少对于CPython,有pydoc,虽然没有正式声明,但导入文件就是它的作用:
from pydoc import importfile
module = importfile('/path/to/module.py')
PS。为了完整起见,在撰写本文时,这里提到了当前的实现:pydoc.py,我很高兴地说,在xkcd 1987的脉络中,它没有使用第21436期中提到的任何一个实现,至少没有逐字逐句地使用。
我并不是说它更好,但为了完整起见,我想建议在Python2和Python3中使用exec函数。
exec允许您在全局作用域或作为字典提供的内部作用域中执行任意代码。
例如,如果您有一个模块存储在带有函数foo()的“/path/to/module”中,您可以通过执行以下操作来运行它:
module = dict()
with open("/path/to/module") as f:
exec(f.read(), module)
module['foo']()
这使得动态加载代码更加明确,并赋予您一些额外的功能,例如提供自定义内置功能的能力。
如果通过属性而不是键访问对你来说很重要,你可以为全局变量设计一个自定义dict类,提供这样的访问,例如:
class MyModuleClass(dict):
def __getattr__(self, name):
return self.__getitem__(name)