我正在动态创建一些我想在包装器中运行的python代码。这是一个过于简化的例子。
[wrapper.py]
import cv2
img = cv2.imread('pic.png',0)
__import__("fragment")
cv2.imshow('pic',img)
[fragment.py]
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
我希望包装器设置任何导入和变量,然后导入将执行填充的片段(即使图像灰度),然后执行一些标准化的操作(即显示图像)。
片段将会发生变化(遗传算法),所以我宁愿将它们与设置分开,这将是不变的,只会使片段操作更复杂。
当我运行程序时,我得到了片段的依赖性错误,因为没有定义cv2和img(范围错误)。有没有办法通过对上面使用的方法或其他方法进行修正来实现这一目标?
我希望我也可以在ram中创建文件的组合,然后执行它或者用包含所有必需包装的自身版本来写入片段,但是我想知道是否有某些东西首先是清洁工。
真诚的,保罗。
答案 0 :(得分:0)
片段将会改变(遗传算法),所以我更喜欢 将它们与将保持不变的设置分开 只是让操作碎片变得更复杂。
无论您在fragment.py
中实现的遗传算法的复杂程度如何,我都没有看到导入cv2
(以及最终更多模块)将如何以某种方式影响它。
但是,我同意您声明的第一部分,因为您希望尊重 separation of concerns 的原则并使您的代码更清晰。
我为您的问题看到的解决方案是设置一个配置文件config.py
,您可以在其中设置所有导入。但是将config.py
导入其他文件是没用的,除非您成功地在其他地方创建cv2
等模块。您可以通过config.py
文件中的 dynamically importing them 来实现这一目标:
cv2=__import__('cv2')
在您的主程序,fragment.py
文件或任何模块中,只需运行此代码即可使用cv2
:
import config
config.cv2.imread('pic.png')
import config
↔您不再需要运行:import cv2
。这是因为这个技巧将cv2
渲染为可在多个模块中使用的全局变量。
同样的想法适用于您需要在img
文件中声明的其他变量,例如config.py
。
鉴于这些事实,这是我的问题解决方案。请注意,我没有使用类和函数:我更喜欢直接解决您的问题,而是让事情过于简单明了。
代码组织:
config.py
文件对应于您的wrapper.py
:
solution/
├── application.py
├── cfg
│ ├── config.py
│ └── __init__.pyc
├── gallery
│ └── pic.png
└── genalgos
├── fragment.py
└── __init__.py
<强> config.py:强>
# This will make cv2 global and thus you won't need to import it in ./genalgos/fragment.py
# You can use the same idea for all your other imports
cv2=__import__('cv2')
imgc=cv2.imread('./gallery/pic.png') # imgc is global
<强> fragment.py:强>
# The only import you can not avoid is this one
import cfg.config
# imgs is global
# By importing cfg.config you do not need to import cv2 here
imgf=cfg.config.cv2.cvtColor(cfg.config.imgc,cfg.config.cv2.COLOR_BGR2GRAY)
<强> application.py:强>
import cfg.config
import genalgos.fragment
if __name__=="__main__":
"""
Display the image 'imgc' as it is in 'cfg/config' file
"""
cfg.config.cv2.imshow('Pic in BGR',cfg.config.imgc)
cfg.config.cv2.waitKey(0)
cfg.config.cv2.destroyAllWindows()
"""
Display the grascaled image 'imgf' as it is in 'genalgos/fragment' file which
itself is obtained after transforming imgc of 'cfg/config' file.
"""
cfg.config.cv2.imshow('PIC Grayscaled',genalgos.fragment.imgf)
cfg.config.cv2.waitKey(0) # Press any key to exit
cfg.config.cv2.destroyAllWindows() # Unpaint windows and leave