如果需要第一个函数,如何在脚本中执行第二个函数?

时间:2017-07-20 18:19:42

标签: python function

我认为这是基本的,我已经看到了我问的问题的多个版本,尽管它们并不完全是我所面对的。

我目前有一个带有两个函数的脚本,我希望能够唤起第二个函数,但它需要运行第一个函数。我的脚本仍然很乱,所以我使用的是一个例子:

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将获取该原始结果并对其进行修改。如果需要,我希望能够看到原始和修改后的结果。

3 个答案:

答案 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找到的结果存储在对象中,因此它们始终关联在一起。在你的情况下,这可能是做你想做的最干净的方式。