我认为这是基本的,我已经看到了我问的问题的多个版本,尽管它们并不完全是我所面对的。
我目前有一个带有两个函数的脚本,我希望能够唤起第二个函数,但它需要运行第一个函数。我的脚本仍然很乱,所以我使用的是一个例子:
def func1(input): # Does something with input data
my_list = []
for i in input:
my_list.append(i)
return my_list # Returns a list
func1_list = func1(x) # Save the result from func1 into a variable
def func2(func1_list):
my_final_list = [] # This function just edits the first list
for val in my_list: # Results from func2 are needed later on
temp = val**3
my_final_list.append(temp)
return my_final_list
有没有办法执行第二个函数而不必在导入脚本时调用第一个函数?我不知道在func2中输入func1_list变量的位置,这样任何人都可以直接进入func2并运行它(它会自动执行func1)。
编辑: func1和func2都应该能够单独执行 - func2依赖于func1。两者都将显示信息(func2只显示修改后的信息)。示例:func1将运行一些输入并显示原始结果,而func2将获取该原始结果并对其进行修改。如果需要,我希望能够看到原始和修改后的结果。
答案 0 :(得分:0)
如果希望if __name__ == '__main__':
func1_list = func1(x) # Save the result from func1 into a variable
仅在直接执行脚本时调用,则需要稍微修改一下脚本,以便在从模块调用时忽略它。你将使用这样的if条件:
__name__
__main__
仅在直接调用脚本时等于{{1}},因此从模块调用时不会执行。
有关其工作原理的详细说明,请查看here。
答案 1 :(得分:0)
如果您尝试导入脚本,则必须遵循最佳做法和惯例。
在不开始构建完整包的情况下,您至少需要确保在导入模块时不执行未请求的代码。
要么将代码包装到class
中,要么从模块的根目录中删除函数调用,并提供init_function()
,必须调用它来准备环境。
使用init_function()并没有什么可耻的,很多库都这样做。
但是,我建议您在Python classes内构建代码。 FunctionsManager.py
的示例:
class FunctionsManager:
def __init__(self):
self.func1_list = self.func1(x) # Save the result from func1 into a variable
def func1(self, input): # Does something with input data
my_list = []
for i in input:
my_list.append(i)
return my_list # Returns a list
def func2(self, func1_list):
my_final_list = [] # This function just edits the first list
for val in my_list: # Results from func2 are needed later on
temp = val**3
my_final_list.append(temp)
return my_final_list
然后在你的主要代码中:
from FunctionsManager import FunctionsManager
manager = FunctionsManager() # Calls __init__() and so func1()
result = manager.func2(yourlist)
答案 2 :(得分:0)
请注意,您的问题基本上是要求dependency injection上的入门读物。你可能会很好地阅读它。它与语言无关 - 它与Java一样适用于Python。
您可以采取几种不同的方法;最好的选择取决于您的需求以及所涉及的功能(这就是我在评论中提出所有问题的原因)。
您正在寻找的最简单的形式是让一个函数调用另一个函数。 (COLDSPEED参考了这个。):
def func1(input):
# do some magic to my_list with input
return my_list
def func2(input):
func1_list = func1(input)
# do some magic to make func2's my_list
return my_list
在这种情况下,func1和func2都可以被调用。导入代码不必担心在func2之前调用func1 - 这是由func2处理的。
在我进入你的其他选择之前,你提到两个函数都输出信息。将计算与输出分开是一种很好的做法。所以,不要这样做:
def func1(input):
# do some magic to my_list with input
print("func1: Stuff from my list...")
return my_list
def func2(input):
func1_list = func1(input)
print("func2: Stuff from my list...")
# do some magic to make func2's my_list
return my_list
因为然后调用func2
将打印出“func1”行和“func2”行。相反,将逻辑与输出分开。它可能看起来更复杂,但它为您提供了更多的构建块:
def func1(input):
# do some magic to my_list with input
return my_list
def func2(input):
func1_list = func1(input)
# do some magic to make func2's my_list
return my_list
def output_func1(input):
func1_list = func1(input)
print("func1_list stuff")
def output_func2(input):
func2_list = func2(input)
print("func2_list stuff")
现在你有很多可重复使用的功能,不会产生很多噪音。
这是一个很好的步骤,您可以轻松使用它。如果func1
需要一个小时才能运行,会发生什么?如果已经运行它,您不想再次运行它。然后你想使用模块变量来保存状态。像这样:
func1_results = None
def func1(input):
# do some magic to my_list with input
func1_results = my_list
return my_list
def func2(input):
if not func1_results:
func1(input) # this will only run if func1 hasn't been called yet
# do some magic to make func2's my_list
return my_list # you could similarly make a construct to save these results
现在只有在需要时才能获得调用其依赖项的代码。我们越来越好了。但我们将输入传递给func2,我们只关心它在func1中。您可以创建func1引用的模块变量input
,并且您的导入代码可以在调用任何func之前设置它:
input = None
def func1():
# do some magic to my_list with module variable input
并将其调用为:
import my_funcs
my_funcs.input = "Happy happy input!"
my_funcs.func1() # or just my_funcs.func2(), etc.
这可能很好,但这很危险 - 如果导入代码没有设置input
怎么办?解决方案是Fabien提到的有关课程的内容:
class FuncRunner(object):
def __init__(self, input):
self.input = input
self.func1_results = None
def func1(self):
# do some magic to local my_list with input
self.func1_results = my_list
return my_list
def func2(self):
if not self.func1_results:
self.func1()
# do some magic to make func2's my_list
# maybe save the result as self.func2_results ?
return my_list
这将被调用为:
from my_funcs import FuncRunner
runner = FuncRunner("Happy happy input!")
foo = runner.func1() # or foo = runner.func2(), as per your needs
这样做的好处是不让你在不构造对象的情况下运行函数,以及__init__
的结构方式,你不能在不传递input
的情况下创建对象。 func1
找到的结果存储在对象中,因此它们始终关联在一起。在你的情况下,这可能是做你想做的最干净的方式。