如何调用公共子模块(存在于各种模块中),从值中选择正确的模块?
示例:
假设我有这个文件夹结构:
myprogram/
myprogram.py #main program
colors/ #colors package
__init__.py #contains __all__
blue/ #blue module
paint.py #submodule
red/ #red module
paint.py #submodule
paint子模块在每个模块中都有相同的名称,但每个模块都有不同的代码。
在myprogram.py中我想做这样的事情:
import colors #import all the colors modules
my_shape = circle()
my_color = "blue" #define the module to call by his name
if my_color in colors:
colors.my_color.paint(my_shape) #calls the submodule from the right mosule
我希望“colors”包可以扩展,所以我可以轻松地从一个部署中删除一种颜色,而且只需要很少的工作量。
(我可以制作一个带有内部情况的paint.py模块,但它不容易扩展)
问题是:
if my_module in package
事情?package.my_module_variable.function()
来调用包的模块吗?我正在尝试解决这个storing functions into dicts,我是否以正确的方式?
答案 0 :(得分:1)
您应该能够将颜色子模块视为属性。子模块在其directorys中需要__init__.py
个文件(例如blue/__init__.py
)以及paint.py
模块。然后你可以做这样的事情:
my_color = "blue"
if hasattr(colors, my_color):
getattr(colors, my_color).paint(my_shape)
但请注意,在您的示例中,paint
是一个模块,因此您无法调用该模块。如果paint
模块中有paint
函数,那么您可以执行以下操作:
getattr(colors, my_color).paint.paint(my_shape)
编辑:我应该像其他人一样提到,对于您所展示的示例而言,这似乎有些过分。如果您的真实代码/情况比这更复杂,那就去吧。否则一个不错的选择可能是让一个带有字典的绘图模块用于各种操作。因此像colors/paint.py
这样的文件可以包含:
def paint_blue(shape):
print("BLUE!")
def paint_red(shape):
print("RED!")
paint_funcs = {
"blue": paint_blue,
"red": paint_red,
}
def paint(color, shape):
return paint_funcs[color](shape)
编辑2 :
颜色目录中的__init__.py
文件需要将它们视为子包,否则您无法导入它们。除非主包知道子模块,否则我使用这样的属性的初始方法将无法工作。例如:
import colors
# colors doesn't know it has submodules 'blue' and 'red'
from colors import *
# if the colors __init__ has an __all__ declaration now it does know about them
hasattr(colors, "blue") # will work
或者您可以导入颜色__init__.py
模块
# in colors/__init__.py
import blue
import red
或者你可以做别人对动态导入所说的话。
答案 1 :(得分:0)
如果您知道模块文件的路径,可以使用imp
模块动态加载模块:
import imp
my_color = "blue"
paint = imp.load_source('paint', 'colors/'+my_color+'/paint.py')
和paint
可以用作常规模块,就像导入时使用:
from colors import blue.paint as paint