总而言之,我有以下“错误”的调度程序:
def _load_methods(self):
import os, sys, glob
sys.path.insert(0, 'modules\commands')
for c in glob.glob('modules\commands\Command*.py'):
if os.path.isdir(c):
continue
c = os.path.splitext(c)[0]
parts = c.split(os.path.sep )
module, name = '.'.join( parts ), parts[-1:]
module = __import__( module, globals(), locals(), name )
_cmdClass = __import__(module).Command
for method_name in list_public_methods(_cmdClass):
self._methods[method_name] = getattr(_cmdClass(), method_name)
sys.path.pop(0)它会产生以下错误:
ImportError:没有名为commands.CommandAntitheft的模块
其中Command*.py位于modules\commands\文件夹
有人能帮我吗?
一种可能的解决方案(它有效!)是:
def _load_methods(self):
import os, sys, glob, imp
for file in glob.glob('modules/commands/Command*.py'):
if os.path.isdir(file):
continue
module = os.path.splitext(file)[0].rsplit(os.sep, 1)[1]
fd, filename, desc = imp.find_module(module,
['./modules/commands'])
try:
_cmdClass = imp.load_module( module, fd, filename, desc).Command
finally:
fd.close()
for method_name in list_public_methods(_cmdClass):
self._methods[method_name] = getattr(_cmdClass(), method_name)它仍然是所有的风险,由博本斯(坦克:-) ),但现在我能够加载命令在“运行时”
发布于 2009-04-15 13:33:24
模块命令(0,‘
\sys.path.insert’)
最好不要将相对路径放到sys.path中。如果当前目录在执行过程中发生变化,它将崩溃。
此外,如果您从脚本的不同目录运行,它将无法工作。如果要使其相对于脚本的位置,请使用文件。
此外,出于安全考虑,应该将‘\’字符转义为‘\’,实际上它应该使用os.path.join()而不是依赖于Windows path规则。
sys.path.insert(0, os.path.abspath(os.path.join(__file__, 'modules')))sys.path.pop(0)
很危险。如果另一个导入的脚本使用了sys.path (可能是这样),那么您就走错了路。此外,重新加载您自己的模块也会中断。最好让路径保持原样。
模块,名称= '.'.join(部件),部件-1:
请记住,您的路径包括段‘modules’。所以你实际上是在试着:
import modules.commands.CommandSomething但是由于‘modules.commands’已经在您添加的搜索路径中,所以您真正想要的只是:
import CommandSomething__import__(模块,全局变量(),本地变量(),名称)
‘fromlist’也是一个列表,所以如果你真的想让它把‘CommandSomething’写到你的局部变量中,它应该是‘name’。(几乎可以肯定的是,您不希望这样;将want列表保留为空。)
_cmdClass =__import__(模块).Command
是的,这是行不通的,模块是一个模块对象,而__import__需要一个模块名称。您已经有了模块对象;为什么不只使用“module.Command”呢?
我对这一切的反应很简单:太神奇了。
你的 使这对你自己来说太困难了,并且通过摆弄导入系统的内部而制造了许多潜在的问题和脆弱性。即使对于有经验的Python程序员来说,这也是一件棘手的事情。
使用显式导入的普通旧式Python模块几乎肯定会更好。硬编码命令列表真的不是很困难;将所有命令都放在一个包中,__init__.py说:
__all__= ['ThisCommand', 'ThatCommand', 'TheOtherCommand']可以重复文件名一次,但比过多的魔术简单和健壮得多。
发布于 2009-04-15 18:41:05
你真的需要把东西作为模块导入吗?如果您只是从文件系统中的任意位置加载代码,那么您可以只使用execfile,而不是摆弄模块路径等。
即。
for file in glob.glob('modules/commands/Command*.py'):
if os.path.isdir(file):
continue
moddict={}
execfile(file, moddict)
_cmdClass = moddict['Command']
...https://stackoverflow.com/questions/751455
复制相似问题