【问题标题】:loading class in Python from a string name从字符串名称在 Python 中加载类
【发布时间】:2016-02-10 15:45:37
【问题描述】:

我有一系列类名,想检查它们并导入它们。如何做到这一点:

CName='Class_blahblah'
from eval(CName) import *  

这是我得到的:

 SyntaxError: invalid syntax

确切地说:我在 IDE 中的 FEA 软件中运行了几个类,我对它们中的每一个都执行如下操作:

if 'Class_SetSurfPart' in sys.modules:  
    del sys.modules['Class_SetSurfPart']
    print 'old module Class_SetSurfPart deleted'
    from Class_SetSurfPart import *
    reload(sys.modules['Class_SetSurfPart'])
else:
    from Class_SetSurfPart import *

但我想将所有类名放在一个列表中并作为循环执行此操作,而不是对所有类执行此操作。

【问题讨论】:

  • 这是answer 你要找的吗?
  • 不,假设i=__import__('dupList', fromlist=['']) 我得到>>> i 所以我得到<module 'dupList' from 'D:\\My Pythons\dupList.py'>。我得到的错误是>>> dupList([1, 2, 3, 4, 1, 2, 3])NameError: name 'dupList' is not defined

标签: python string class


【解决方案1】:

你想要importlib.import_module:

bruno@bigb:~/Work/playground/imps$ ls pack/
__init__.py  stuff.py  
bruno@bigb:~/Work/playground/imps$ cat pack/stuff.py
class Foo(object):
    pass
bruno@bigb:~/Work/playground/imps$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
>>> import importlib
>>> module = importlib.import_module("pack.stuff")
>>> module
<module 'pack.stuff' from 'pack/stuff.pyc'>
>>> # now you can either use getattr() or directly refer to `module.Foo`: 
>>> cls = getattr(module, "Foo")
>>> cls
<class 'pack.stuff.Foo'>
>>> module.Foo
<class 'pack.stuff.Foo'>
>>> module.Foo is cls
True

【讨论】:

  • 它会加载模块,但是当我以这种方式运行模块时,它会在模块内部出现错误,而当我通常使用 from Class_mmm import * 加载模块时,它工作得很好。
  • "star imports" (from module import *) 很糟糕,永远不应该在生产代码中使用它们(真的,在这里做过等等) - 尝试时将此“功能”视为一个方便的快捷方式在 Python shell 中取出东西 - 所以无论如何都应该做你应该做的事情:要么使用限定路径(即 module.Foo 而不是 Foo),要么显式绑定名称空间中的名称(即:Foo = module.Foo
【解决方案2】:

把钥匙放在

上可能是个好主意
sys.modules
在这样的列表中:
keys = [key for key in sys.modules]

请记住,每个项目都存储为字符串类型。

#I'm assuming that you've already made a list of the classes you want to be 
#checking for in a list. I'll call that list classes.
for name in classes:
    if name in keys:
        del sys.modules[name]  #remember that this does not delete it permanently.
        print "Old module {} deleted".format(name)
        name = __import__(name)
        reload(name)
    else:
        __import__(name)

【讨论】:

  • 这不起作用。它说导入的不起作用。
  • 您要导入的模块的名称是什么?另外,请确保文件上没有文件扩展名(.py、.txt 等)。
  • 有一些类我想作为循环加载。其中之一是Class_VerticesEdgesPart
  • if 'Class_SetSurfPart' in sys.modules: del sys.modules['Class_SetSurfPart'] print 'old module Class_SetSurfPart deleted' from Class_SetSurfPart import * reload(sys.modules['Class_SetSurfPart']) else: from Class_SetSurfPart import *
  • 重载功能的意义何在?简单地在 sys.modules 上使用 del 不会永久改变它。
猜你喜欢
  • 1970-01-01
  • 2012-03-23
  • 1970-01-01
  • 1970-01-01
  • 2013-02-17
  • 2014-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多