在收到所有参数之前,我们可以使用关键字参数和咖喱吗?

问题描述 投票:0回答:1

我们可以使用关键字参数和咖喱函数,直到以任何顺序接收到所有参数?

例如,我有这个代码:

def create_folder_transformer(folder):
    return lambda predicate: lambda file_transformer: map(file_transformer,
        filter(predicate,
            os.listdir(folder)))

我可以创建一个带有特定文件夹的folder_transformer然后提及`预测等等。但它有一个特定的顺序。但是,我不认为它需要与该订单挂钩。

我希望实现这样的目标:

  1. 如果我通过predicate,我得到一个部分函数,​​它将folderfile_transformer作为参数。现在,如果我提供folder,我得到一个部分函数,​​需要file_transformer
  2. 如果我通过file_transformer,我得到一个部分函数,​​它将predicatefolder作为参数。现在,如果我提供predicate,我得到一个部分函数,​​需要folder

简而言之,是否有一个内置的部分创建者递归地继续生成部分函数,​​直到获得所有输入;如果满足输入只需执行代码。我相信它在Haskell中称为currying,它是函数默认执行的方式。

我觉得它可能有用的用例:

  1. 当我用folder操作转换特定的n时,用folder创建一个部分会更好。
  2. 当我有一个特定的谓词时 - 在许多文件夹中过滤掉mp4文件 - 像predicate这样的string.endswith(".mp4")部分会更好。

我读了部分docs,但如果我没有填写一些args,这些部分不会返回部分。但是因为我已经宣布它为None,我也不能指望它。理想情况下,我希望我的函数本身表现得像那样,甚至不用担心使用像partial这样的附加函数,即它应该被烘焙到我的函数中。

def folder_transformer(folder=None, predicate=None, transformer=None):
    return map(transformer, filter(predicate, os.listdir(folder)))

file_transformer = partial(folder_transformer, predicate=os.path.isfile)

# This gives me a "map" object, but I want another partial takes "transformer".
current_transformer = file_transformer(folder=folder)
# This works, but my question is can I make my function do this automatically. 
current_transformer = partial(file_transformer,folder=folder)
python functional-programming currying partials
1个回答
0
投票

我带了一个小脚本供我个人使用。

PS:如果有人知道可以做类似的图书馆,请告诉我。

import inspect

def curry(function):
    original_func = function
    original_args = inspect.signature(function).parameters

    def wrapper(**kwargs):
        call = True
        current_args = {}
        for each in original_args:
            if kwargs.get(each):
                current_args[each] = kwargs.get(each)
            else:
                call = False
        if call:
            original_func(**current_args)
        else:
            def partial(**nargs):
                current_args.update(nargs)
                return wrapper(**current_args)
            return partial

    return wrapper

@curry
def foo(a=None, b=None, c=None):
    print(a, b, c)

# first partial
bar_with_a = bar(a=1)
# next partial
bar_with_a_and_b = bar_with_a(b=1)
# next partial
bar_with_a_and_b = bar_with_a_and_b(b=2)
# next partial
bar_with_a_and_b = bar_with_a_and_b(a=2)
# call
bar_with_a_and_b(c=2)
© www.soinside.com 2019 - 2024. All rights reserved.