我一直在考虑这个问题太久了,并且没有任何想法,也许你们中的一些人可以提供帮助。
我有一个python脚本文件夹,所有这些脚本都有相同的周围体(字面意思是我从shell脚本生成它),但是有一个块与所有块不同。换句话说:
Top piece of code (always the same)
Middle piece of code (changes from file to file)
Bottom piece of code (always the same)
我今天意识到这是一个坏主意,例如,如果我想从顶部或底部更改某些内容,我需要编写一个shell脚本来执行此操作。 (这不是那么难,它看起来似乎是非常糟糕的代码)。
所以我想做的是,有一个外部python脚本是这样的:
Top piece of code
Dynamic function that calls the middle piece of code (based on a parameter)
Bottom piece of code
然后文件夹中的每个其他python文件都可以简单地作为中间代码。但是,普通的模块在这里不起作用(除非我弄错了),因为我会得到我需要从arguement执行的代码,这将是一个字符串,因此我不知道在运行时运行哪个函数
所以我想到了另外两个解决方案:
我可以使用:
os.command(sys.argv [0] scriptName.py)
会运行脚本,但调用python来调用python对我来说似乎不太优雅。
那么有没有人有任何其他想法?谢谢。
答案 0 :(得分:4)
如果您将函数的名称知道为字符串,并将模块的名称作为字符串知道,那么您可以
mod = __import__(module_name)
fn = getattr(mod, fn_name)
fn()
答案 1 :(得分:4)
另一种可能的解决方案是让每个重复文件从主文件中导入功能
from topAndBottom import top, bottom
top()
# do middle stuff
bottom()
答案 2 :(得分:2)
除了已发布的几个答案之外,请考虑Template Method设计模式:制作一个抽象类,例如
class Base(object):
def top(self): ...
def bottom(self): ...
def middle(self): raise NotImplementedError
def doit(self):
self.top()
self.middle()
self.bottom()
然后,每个可插入模块都会创建一个继承自此Base
的类,并且必须使用相关代码覆盖middle
。
对于这个简单的情况可能没有保证(你仍然必须导入正确的模块才能实例化它的类并在其上调用doit
),但仍然值得记住(连同它的许多Pythonic变种)对于“可插件”的数量或复杂程度不断增长的情况,我已经在youtube上的许多技术演讲中充分解释了这一点 - 模板方法(尽管名称可怕;-)是一个坚实的,经过充分验证的可扩展的模式[[有时太过刻板,但这正是我在那些许多技术会谈中所说的 - 而且这个问题不适用于这个特定的用例]]。
答案 3 :(得分:0)
然而,正常的模块在这里不起作用(除非我弄错了),因为我会得到我需要从arguement执行的代码,这将是一个字符串,因此我不知道哪个函数运行到运行时。
它可以正常工作 - 使用__import__
内置,或者,如果你有非常复杂的布局,imp模块可以导入你的脚本。然后你可以通过module.__dict__[funcname]
得到函数。
答案 4 :(得分:0)
导入一个模块(正如其他答案中所解释的)绝对是更清洁的方法,但如果出于某种原因无效,只要你没有做任何太奇怪的事情就可以使用{{3 }}。它基本上运行另一个文件的内容,就好像它被调用exec
时包含在当前文件中一样。它是Python与许多shell中包含的source
语句最接近的东西。至少应该是这样的:
exec(open(filename).read(None))
答案 5 :(得分:0)
这个怎么样?
function do_thing_one():
pass
function do_thing_two():
pass
dispatch = { "one" : do_thing_one,
"two" : do_thing_two,
}
# do something to get your string from the command line (optparse, argv, whatever)
# and put it in variable "mystring"
# do top thing
f = dispatch[mystring]
f()
# do bottom thing