使用python运行具有不同参数的函数

Posted

技术标签:

【中文标题】使用python运行具有不同参数的函数【英文标题】:run functions with differents parameters with python 【发布时间】:2021-11-20 14:00:40 【问题描述】:

我有想要使用不同参数运行的函数

目录结构如下:

App/  
   ├─ main.py
   └─ fcts1.py
   └─ fcts2.py
   └─ File1.csv
   └─ File2.csv
   └─ Files/  
      └─B.xlsx
      └─A.txt
      └─C.xlsx

Exp 1:

file1 = "file1.csv"
from fcts1 import fct1

    def A_fct(fileA):
        df = pd.read_csv(file1)
        dfA = pd.read_csv(fileA,skiprows=2,sep=r"\s*\|\s*")
        fct1()
    def B_fct(fileB):
        df = pd.read_csv(file1)
        dfB = pd.read_excel(fileB)
        fct1()
    def C_fct(fileC):
        df = pd.read_csv(file1)
        dfC = pd.read_excel(fileC)
        fct1()

经验 2:

file2 = "file2.csv"
from fcts2 import fct1

    def A_fct(fileA):
        df = pd.read_csv(file2)
        dfA = pd.read_csv(fileA,skiprows=2,sep=r"\s*\|\s*")
        fct1()
    def B_fct(fileB):
        df = pd.read_csv(file2)
        dfB = pd.read_excel(fileB)
        fct1()
    def C_fct(fileC):
        df = pd.read_csv(file2)
        dfC = pd.read_excel(fileC)
        fct1()

NB1: fcts1.py 中的 fct1() 与 fcts2.py 中的 fct1() 不同

NB2:每个函数都执行特定的任务

我已经用关系 file_name => 函数定义了一个字典,因为我想读取文件名(A/B/C..)并为 Files 文件夹中的每个文件调用可调用函数

name_to_func = 
    "A": A_fct,
    "B": B_fct,
    ...

然后遍历文件夹中的文件,并调用函数

import os

path = '/your/path/here'

name_to_func = 
    "A": A_fct,
    "B": B_fct


for file_name in os.listdir(path):
    file_prefix = file_name.split('.')[0]
    name_to_func[file_prefix](file_name)

有时我想使用 fcts1.py 文件中的 df = pd.read_excel(file1)fct1() 运行这些函数,有时使用 df = pd.read_excel(file2)fct1() 来自文件 fcts2.py 请问我该怎么做?

【问题讨论】:

【参考方案1】:

您可以将这 6 个函数替换为一个:

def fct(file_number, file_letter, function):
    # Key idea: you can pass functions as arguments
    df = pd.read_excel(file_number)
    dfA = pd.read_excel(file_letter)
    function()

可以这样调用:

import fcts1, fcts2

fct("file1.csv", whatever_file, fcts1.fct1)
fct("file2.csv", whatever_file, fcts2.fct1)

【讨论】:

不,我不能每个函数都执行特定任务 您发布的代码是否不能代表您实际运行的代码?据我了解,您发布的代码中的函数执行完全相同的任务。 是的,这不是我实际运行它的代码,只是一个 exp 只要您问题中的代码不能代表您正在运行的代码,您可能会得到不相关的答案。这些示例包含实际代码的所有最重要的属性,这一点很重要。您说实际功能执行不同的任务,但您问题中的功能执行相同的操作。答案可能会解决这个问题,因为这是一个明显的简化,但显然这对您没有帮助,因为您的代码实际上是不同的。请参阅:minimal reproducible example。 (IMO,说“每个函数都执行特定任务”是不够的,因为这段代码不是这样)【参考方案2】:

考虑在main.py 的顶部创建一个设置/参数字典,然后将其传递给您的主函数。本质上,这意味着您只需要修改这个字典,而不是代码本身,就可以使用不同的文件或函数重新运行您的分析。

例子:

from fcts1 import fct1 as function1
from fcts2 import fct1 as function2

SETTINGS = 
    'file1': "file1.csv",
    'file2': "file2.csv",
    'function': function1,


def main(file1, file2, function):
    df1 = pd.read_excel(file1)
    df2 = pd.read_excel(file2)
    function()


if __name__ == '__main__':
    main(**SETTINGS)

需要注意的两点:

我将fct1s 别名为function1function2,以便能够区分它们。实际上,您的代码会受益于更好的变量名称。 我们在main(**SETTINGS) 中使用星号表达式,这意味着只要字典的键名与函数的参数名匹配,SETTINGS 字典中的参数就会正确地传递给main 函数。李>

【讨论】:

谢谢,但实际上我想使用文件 1 或文件 2,而不是同时使用两者 我不确定我是否理解您想要实现的目标。如果您只需要file1file2,则只需要字典中的一个“文件”键。 是的,但是如何在我的所有函数中自动传递 SETTINGS 字典中的参数?【参考方案3】:

据我了解

你有 3 个函数来读取 file1 的文件 A、B、C,然后在 fcts1 中调用 fct1()

另外3个函数读取file2的fileA,B,C,然后在fcts2中调用fct1()

你想在这两种情况之间切换,对吧?

为这两种情况在 name_to_func 添加另一层可能会解决您的问题

import os

from fcts1 import fct1 as f1
from fcts2 import fct1 as f2

file1 = "file1.csv"
file2 = "file2.csv"

def f1_A_fct(fileA):
    df = pd.read_csv(file1)
    dfA = pd.read_csv(fileA,skiprows=2,sep=r"\s*\|\s*")
    f1()
def f1_B_fct(fileB):
    df = pd.read_csv(file1)
    dfB = pd.read_excel(fileB)
    f1()
def f1_C_fct(fileC):
    df = pd.read_csv(file1)
    dfC = pd.read_excel(fileC)
    f1()

def f2_A_fct(fileA):
    df = pd.read_csv(file2)
    dfA = pd.read_csv(fileA,skiprows=2,sep=r"\s*\|\s*")
    f2()
def f2_B_fct(fileB):
    df = pd.read_csv(file2)
    dfB = pd.read_excel(fileB)
    f2()
def f2_C_fct(fileC):
    df = pd.read_csv(file2)
    dfC = pd.read_excel(fileC)
    f2()


name_to_func = 
    "A": "f1": f1_A_fct, "f2": f2_A_fct,
    "B": "f1": f1_B_fct, "f2": f2_B_fct,
    "C": "f1": f1_C_fct, "f2": f2_C_fct


def get_func(a_b_c, f1_f2):
    return name_to_func[a_b_c][f1_f2]


# set to 'f1' if you want to run with df = pd.read_excel(file1) and fct1() from the file fcts1.py
# set to 'f2' if you want to run with df = pd.read_excel(file2) and fct1() from the file fcts2.py
f1_or_f2 = 'f1' 
path = '/your/path/here'
for file_name in os.listdir(path):
    file_prefix = file_name.split('.')[0]
    get_func(file_prefix, f1_or_f2)(file_name)

更新:

如果你只希望 name_to_func 的值包含一个函数而不是另一个字典

添加 if-else 检查即可解决问题

# set to 'f1' if you want to run with df = pd.read_excel(file1) and fct1() from the file fcts1.py
# set to 'f2' if you want to run with df = pd.read_excel(file2) and fct1() from the file fcts2.py
f1_or_f2 = 'f1'

name_to_func = 
    "A": f1_A_fct if f1_or_f2 == 'f1' else f2_A_fct,
    "B": f1_B_fct if f1_or_f2 == 'f1' else f2_B_fct,
    "C": f1_C_fct if f1_or_f2 == 'f1' else f2_C_fct




path = '/your/path/here'
for file_name in os.listdir(path):
    file_prefix = file_name.split('.')[0]
    name_to_func[file_prefix](file_name)

【讨论】:

感谢您回答我,是的,您非常了解我,只是我只想将一个函数保留给 A,然后选择使用哪些函数(f1 或 f2)来运行它。 只保留一个函数 A ,这是否意味着您希望 name_to_func 的值是函数而不是字典?如果是,您可以将"f1": f1_A_fct, "f2": f2_A_fct 更改为f1_A_fct if f1_or_f2 == 'f1' else f2_A_fct 并将f1_or_f2 = 'f1' 行移到上面。然后你可以像你的代码一样运行它name_to_func[file_prefix](file_name) 是的,这就是我的意思,我会试试你的解决方案【参考方案4】:

尝试为你的函数使用别名

from fcts1 import fct1 as f1
from fcts2 import fct1 as f2

【讨论】:

以上是关于使用python运行具有不同参数的函数的主要内容,如果未能解决你的问题,请参考以下文章

使用单个命令运行具有不同参数的函数列表

在python中循环具有不同参数的函数

Python函数指针具有不同的参数

使用不同的参数并行运行相同的函数,并知道哪个并行运行在 python 中结束了

具有不同数量的 For 循环的函数(python)

在 AWS Stack 上运行更多具有不同参数的 node.js 应用程序