我正在尝试在 Python 中动态导入模块。现在,我有一个名为“modules”的目录,里面有两个文件;它们是 mod1.py 和 mod2.py。它们是返回时间的简单测试函数(即mod1.what_time('now')返回当前时间)。
从我的主应用程序,我可以导入如下:
sys.path.append('/Users/dxg/import_test/modules')
import mod1
Run Code Online (Sandbox Code Playgroud)
然后执行:
mod1.what_time('now')
Run Code Online (Sandbox Code Playgroud)
它有效。
我并不总是会知道目录中有哪些模块可用。我想import如下:
tree = []
tree = os.listdir('modules')
sys.path.append('/Users/dxg/import_test/modules')
for i in tree:
import i
Run Code Online (Sandbox Code Playgroud)
但是我收到错误:
sys.path.append('/Users/dxg/import_test/modules')
import mod1
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
所以我试图改变一堆"来自x import x"的语句,看起来像这样:
from class_foo import class_foo
Run Code Online (Sandbox Code Playgroud)
变成动态的东西.我正在尝试将路径传递到目录并让它导入其中的所有模块.
def dynamicImport(dirPath):
filez = os.listdir(dirPath)
for file in filez:
if "class" in file:
oname = file[:-3] #cut off the file extension, trivial
imp_statement = "from " + oname + " import " + oname
#when I print imp_statement, I can verify it's being concatenated correctly
exec(imp_statement)
Run Code Online (Sandbox Code Playgroud)
当我运行此函数并将其传递给路径时,语句字符串正在正确创建并且不会产生错误,但稍后我将尝试访问其中一个导入的对象,并且会发生以下情况:
foo = class_foo()
NameError: name 'class_foo' is not defined
Run Code Online (Sandbox Code Playgroud)
显然,我做错了什么.任何帮助,将不胜感激.
我目前正在编写一个应用程序,允许用户通过"插件"类型架构扩展它.他们可以根据我提供的BaseClass对象编写其他python类,并根据各种应用程序信号加载这些类.在启动应用程序之前,作为插件加载的类的确切数量和名称是未知的,但仅在启动时加载一次.
在我研究解决这个问题的最佳方法的过程中,我提出了两个常见的解决方案.
选项1 - 使用imp,pkgutil等滚动自己.
例如,请参阅此答案或此答案.
选项2 - 使用插件管理器库
随机选择一对
我的问题是-在应用程序必须以加载新的插件重新启动条件-是否有过什么灵感来自上述方法的任何利益这个苏答案和这一个,如:
import inspect
import sys
import my_plugins
def predicate(c):
# filter to classes
return inspect.isclass(c)
def load_plugins():
for name, obj in inspect.getmembers(sys.modules['my_plugins'], predicate):
obj.register_signals()
Run Code Online (Sandbox Code Playgroud)
与上述方法相比,这种方法有任何缺点吗?(除了所有插件必须在同一个文件中)谢谢!
编辑
评论请求进一步的信息...我能想到的唯一额外的事情是插件使用闪烁库来提供他们订阅的信号.每个插件可以订阅不同类型的不同信号,因此必须具有其自己的特定"寄存器"方法.
我有一个关于如何为我的程序设计好的问题.我的程序非常简单,但我希望拥有良好的架构,并使我的程序在未来易于扩展.
我的程序需要从外部数据源(XML)获取数据,从这些数据中提取信息,最后需要准备SQL语句以将信息导入数据库.因此,对于现在存在的所有外部数据源,将来会有我的应用程序的简单"流程":获取,提取和加载.
我正在考虑创建名为DataFetcher,DataExtractor和DataLoader的泛型类,然后编写将继承它们的特定类.我想我需要一些工厂设计模式,但是哪个?FactoryMethod还是抽象工厂?
我也想不要使用这样的代码:
if data_source == 'X':
fetcher = XDataFetcher()
elif data_source == 'Y':
fetcher = YDataFetcher()
....
Run Code Online (Sandbox Code Playgroud)
理想情况下(我不确定这是否容易实现),我想编写新的"数据源处理器",在现有代码中添加一行或两行,我的程序将从新数据源加载数据.
如何利用设计模式来实现目标?如果您可以在python中提供一些示例,那就太棒了.
我有一个脚本可以即时导入模块.由于模块名称在新版本出现后立即更改,因此很难检查脚本中是否也更改了特定模块名称.因此,我将模块名称保存在脚本的顶部,在变量中,如下例所示:
var1 = 'moduleName1_v04'
var2 = 'moduleName2_v08'
...................
import var1
...................
import var2
...................
Run Code Online (Sandbox Code Playgroud)
但如果我这样写,我会收到错误.
问题是:如何使用示例中的变量导入模块?可能吗?
我有多个文件,其结构类似于文件example.py:
def initialize(context):
pass
def daj_omacku_teplu(context, data):
pass
def hmataj_pomaly(context, data):
pass
def chvatni_paku(context, data):
pass
def mikaj_laktom(context, data):
pass
Run Code Online (Sandbox Code Playgroud)
我需要能够在不同的 python 文件中从“example.py”动态导入方法,例如:
for fn in os.listdir('.'):
if os.path.isfile(fn):
from fn import mikaj_laktom
mikaj_laktom(example_context, sample_data)
Run Code Online (Sandbox Code Playgroud)
由于多种原因,我无法更改 的结构,example.py因此我需要制定一种机制来加载方法并评估它们。我尝试使用importlib但它只能导入一个类,而不是只定义了方法的文件。谢谢您的帮助。
我正在使用Pythons logging模块。我想记录一条消息的完整路径,例如
“ msg packagename.modulename.functionName lineNumber”,但是如何获取消息的软件包名称?
日志记录配置为:
LOGGING = {
'formatters': {
'simple': {
'format': '[%(levelname)s] %(message)s [%(module)s %(funcName)s %(lineno)d]'
},
},
'handlers': {
'console': {
'level':'INFO',
'class':'logging.StreamHandler',
'formatter':'simple',
}
},
'loggers': {
'develop': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
},
}
Run Code Online (Sandbox Code Playgroud)
}
我得到了这样的记录器:
logger = logging.getLogger('develop')
Run Code Online (Sandbox Code Playgroud) 我是python的新手.我正在使用python <2.7.我必须在开始时导入一个名字我不知道的文件.实际上我必须通过命令提示符传递文件名,现在我已经读取了名称并存储在变量中,但我不知道如何将它传递给import语句.我正在尝试代码
str = sys.argv[lastIndex]
from "%s" import *,str
Run Code Online (Sandbox Code Playgroud)
但它给出了错误
File "IngestDataToMongo.py", line 86
from "%s" import *,str
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
那怎么做呢.也可以使用python <2.7,因为由于某些原因我无法更改Python的版本或安装运行此代码的任何内容.
我正在尝试动态加载我创建的模块.
现在这可以正常工作:
import structures.index
Run Code Online (Sandbox Code Playgroud)
但如果我通过动态导入它来尝试同样的事情,它就会失败.
struct = __import__("structures.index")
Run Code Online (Sandbox Code Playgroud)
提供的错误是:
Error ('No module named structures.index',)
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
编辑:使用完整范围时(它有用吗?):
struct = __import__("neoform.structures.index")
Run Code Online (Sandbox Code Playgroud)
这不会引发任何错误,但是,它没有加载索引模块,而是加载"neoform"模块.
"struct"的结果是:
<module 'neoform' from '/neoform/__init__.py'>
Run Code Online (Sandbox Code Playgroud)
另外,作为一个附带问题,我如何在动态加载的模块中实例化一个类?(假设所有模块都包含一个公共类名).
编辑:解决方案:(感谢coonj和Rick)这最终成功了.不知道为什么(还),但fromlist必须是"任何东西显然,因为当我把字母"a"作为一个值时它起作用(奇怪的是,假设文件中只有1个类).
def get_struct_module(self, name):
try:
return = __import__("neoform.structures." + name, fromlist='*')
except ImportError, e:
self.out.add("Could not load struct: neoform.structure." + name + "\n\n" + "Error " + str(e.args))
Run Code Online (Sandbox Code Playgroud) 我正在做
module = __import__("client.elements.gui.button", globals(), locals(), [], 0)
Run Code Online (Sandbox Code Playgroud)
但它只会回归client.
我的问题是什么?
python ×10
import ×4
module ×3
architecture ×1
dynamic ×1
loading ×1
logging ×1
plugins ×1
string ×1
syntax-error ×1