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

     2023-03-30     242

关键词:

【中文标题】如果需要第一个函数,如何在脚本中执行第二个函数?【英文标题】:How do you execute the second function in a script if it needs the first function? 【发布时间】:2017-07-20 18:19:42 【问题描述】:

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

我目前有一个包含两个函数的脚本,我希望能够只调用第二个函数,但它需要运行第一个函数。我的脚本仍然很乱,所以我使用了一个示例:

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

【问题讨论】:

从代码的模块范围中删除func1_list = func1(x),然后您可以在不调用func1 的情况下导入。 在调用func2之前编写一个执行func1_list = func1(x)的包装器? 函数是闭包,因此您可以简单地从函数中删除func1_list 参数(并将for val in my_list 更改为for val in func1_list,或者更好:return [val**3 for val in func1_list]。或者您可以使func2致电func1 我认为你需要退后一步,解释一下你真正想要做什么。这个问题本身并没有多大意义,而且很难理解您要解决的基本问题是什么。 可以肯定的是,如果你最终打电话给func2my_list 会给出一个NameError 【参考方案1】:

如果您希望func1_list = func1(x) 仅在直接执行您的脚本时调用,您需要稍微修改您的脚本,以便在从模块调用时忽略它。您将使用这样的 if 条件:

if __name__ == '__main__':
    func1_list = func1(x) # Save the result from func1 into a variable

__name__仅在直接调用脚本时才等于__main__,因此从模块调用时不会执行。


有关其工作原理的详细说明,请查看here。

【讨论】:

哦,我听说过这个,从来没有真正理解过。但是当你说它被直接调用时是什么意思呢?我导入了我的脚本,所以不是直接调用它吗?我也只是尝试将变量放在函数中,这似乎可行,但我不确定这是否是最佳做法。 如果文件名为A.py,则运行python A.py 将导致该行执行。但是在B.py 中执行import A 不会。 @DNAngel 看官方docs。没有比这更正式的了。 哦,好吧,我将不得不解决这个问题。我对如何让我的 func2 在 func1 中使用相同的对象感到困惑,以便它可以在相同的数据集上工作。即 def func2(input) @DNAngel 在 if 条件中,调用 func2(func1_list)。另外,如果这个答案有帮助,您可以接受它(点击灰色复选标记)。【参考方案2】:

如果您尝试导入脚本,则必须遵循最佳实践和约定。

在不开始构建完整包的情况下,您至少需要确保不执行导入模块时未请求的代码。

要么将代码包装到 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)

【讨论】:

感谢您提供的信息。上课总是让我害怕(笑),但我确实想按照最佳实践学习。我是一个完全没有课程的菜鸟,但我会再次阅读它并尝试相应地编辑我的函数!没有冒险,没有收获! 是的,我在这条道路上对你的所有鼓励 :-) 你会发现它比预期的要容易!享受 Python【参考方案3】:

注意,您的问题基本上是在询问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,并且您的导入代码可以在调用任何函数之前设置它:

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

【讨论】:

第二个参数是获取shell脚本函数中第一个参数的内容[重复]

...2312:42:15【问题描述】:我在shell脚本中创建一个函数,我需要传递2个参数。一个是路径,另一个是数组。但问题是第二个参数获取的是第一个参数的内容。例如: 查看详情

如何等待异步函数执行?

...列表(具有唯一ID),第二个获取使用唯一ID的分数。我需要完成第二个http请求(data.map函数),然后发送数据变量值(在res.json中不使用超时)。我知道使用Promises 查看详情

使用脚本中的参数调用第二个脚本

...道在设计时会在这个配置文件中放置什么参数,所以在我需要调用第二个PowerShell脚本的时候,我基本上只有一个变量 查看详情

如何在 Package Body oracle pl/sql 中添加第二个私有函数?

...时间】:2016-12-0501:25:55【问题描述】:大家好,我遇到了一个问题,当我尝试在我的第一个私有标头下方添加第二个私有标头时出现错误。CREATEORREPLACEPACKAGETESTISPROCEDURETEST 查看详情

PL/pgSQL 函数 - 遍历特定列并在循环中执行第二个查询

】PL/pgSQL函数-遍历特定列并在循环中执行第二个查询【英文标题】:PL/pgSQLfunctions-loopthroughspecificcolumnandexecutesecondqueryinloop【发布时间】:2014-03-0914:16:13【问题描述】:正如您在标题中看到的,我想遍历保存建筑物ID的特定列,然... 查看详情

react16.8新特性

...个参数。(无论哪种情况,初始都会执行一遍)情况1,如果没有第二个参数,则每次改变当前函数的state,和初始执行,都会接受回调情况2,如果第二个参数传入的数组变量是state中定义的某个变量,则会当改变这个变量的时候... 查看详情

在javascript中“分阶段”执行函数

...112:22:02【问题描述】:这是我在***上的第一篇文章,所以如果我遇到一个彻头彻尾的傻瓜或者如果我无法让自己完全清楚,请不要对我发火。:-)这是我的问题:我正在尝试编写一个javascript函数,通过检查第一个函数的完成情况... 查看详情

带有数组的函数不起作用

...ysnotworking【发布时间】:2015-04-2905:50:35【问题描述】:我需要制作一个具有三个功能的程序。主函数应该调用第二个函数,将数组作为第一个参数,将数组中的元素数量作为第二个参数。第二个函数传入一个数组和数组中的元素... 查看详情

如何将数组的值作为第二个参数传递给 awk 的 split 函数?

...的方法?我正在尝试在for循环中使用内置拆分函数,并且需要从另一个数组中获取第二个参数(数组名称)并稍后引 查看详情

如果第一个命令启动服务器,如何在 npm 脚本中运行两个命令? [复制]

】如果第一个命令启动服务器,如何在npm脚本中运行两个命令?[复制]【英文标题】:Howtoruntwocommandsinnpmscriptsiffirstcommandstartaserver?[duplicate]【发布时间】:2018-08-2906:03:29【问题描述】:例如,我想通过npm脚本运行两个命令,第一... 查看详情

为啥“使用严格”导致函数未定义

...未定义【发布时间】:2015-07-1016:35:13【问题描述】:我有一个正在加载两个脚本的部分。第二个脚本调用第一个脚本中的一个函数......两个脚本都使用“usestrict;”在顶部。当第二个脚本调用第一个脚本中的函数时,我收到“Uncau... 查看详情

python3定时器

...例:一秒后输出HelloTimer!oneshot的定时器这样就可以实现。如果要实现cycle的定时器,则可以:1s后定时器启动后,将再次以5.5s为间隔周期性执行回调fun_timer函数结果是:在使用Python定时器时需要注意:1.定时器构造函数主要有2个... 查看详情

如何使用 DispatchGroup / GCD 快速顺序执行函数?

...8-02-1205:40:51【问题描述】:在刷新我的集合视图之前,我需要依次运行两个函数。第一个函数从firebase中提取autoids并将它们写入一个数组。然后第二个函数(getLocation)使用该数组再次 查看详情

往shell脚本中传入参数

...  $?----上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0,反之为非0值。  $*----传递给程序的所有参数组成的字符串。  $n----表示第几个参数,$1表示第一个参数,$2表示第二个参数...  $0----当前程序... 查看详情

您如何在 F# 或任何函数式语言中对第二个(或第三个、第四个、...)参数进行 curry?

...题描述】:我刚刚开始使用F#,看看如何使用currying将第一个参数预加载到函数中。但是如何使用第二个、第三个或任何其他参数来做到这一点?命 查看详情

第二个 AJAX 调用中的函数发生在第一个 AJAX 调用之前

】第二个AJAX调用中的函数发生在第一个AJAX调用之前【英文标题】:Functioninside2ndAJAXcallishappeningbeforethe1stAJAXcall【发布时间】:2020-10-1618:21:15【问题描述】:我有两个ajax调用一个接一个地运行。在第二个ajax调用中,一旦收到响应... 查看详情

如何使用正则表达式(或 C# 函数)在一个变量中剪切 TEXT MESSAGE 并从此文本中剪切第二个变量 USERNAME?

】如何使用正则表达式(或C#函数)在一个变量中剪切TEXTMESSAGE并从此文本中剪切第二个变量USERNAME?【英文标题】:Howtocutwitharegularexpression(orC#functions)TEXTMESSAGEinonevariableandthesecondvariableUSERNAMEfromthistext?【发布时间】:2013-09-2823:34:... 查看详情

SVG的JQuery函数,一旦第一个动画完成就执行第二个动画?

】SVG的JQuery函数,一旦第一个动画完成就执行第二个动画?【英文标题】:AJQueryfunctionforSVG,toexecute2ndanimationassoonas,1stanimationcompletes?【发布时间】:2020-09-2917:36:32【问题描述】:我应用了动画延迟技术,但是为了实现手写效果动... 查看详情