Можем ли мы использовать ключевые аргументы и карри, пока не будут получены все аргументы? - PullRequest
0 голосов
/ 12 марта 2019

Можем ли мы использовать ключевые аргументы и curry функцию, пока все аргументы не будут получены в любом порядке?

Например, у меня есть этот код:

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

Я могу создать folder_transformer с определенной папкой, а затем упомянуть «предикат» и т. Д. Но у него есть определенный порядок. Однако я не думаю, что это нужно привязывать к этому порядку.

Я бы хотел достичь чего-то вроде этого:

  1. Если я передам predicate, я получу частичную функцию, которая принимает folder и file_transformer в качестве аргументов. Теперь, если я поставлю folder, я получу частичную функцию, которая принимает file_transformer.
  2. Если я передам file_transformer, я получу частичную функцию, которая принимает predicate и folder в качестве аргументов. Теперь, если я поставлю predicate, я получу частичную функцию, которая принимает folder.

Короче говоря, есть встроенный частичный создатель, который рекурсивно продолжает генерировать частичные функции, пока не будут получены все входные данные; если ввод удовлетворен, просто выполните код. Я считаю, что в Haskell это называется curry , и именно так функции выполняются по умолчанию.

Использование случаев, когда я думаю, что это может помочь:

  1. Когда я преобразую определенный folder с помощью n операций, лучше создать партиал с folder.

  2. Когда у меня есть определенный предикат, такой как - отфильтровать mp4 файлов во многих папках - частичное с predicate, как string.endswith(".mp4") будет лучше.


Я прочитал частичные документы , но эти партиалы не возвращают партиалы, если я не заполнил некоторые аргументы. Но так как я объявил это как None, я тоже не могу этого ожидать. В идеале мне бы хотелось, чтобы сама моя функция вела себя так, даже не беспокоясь об использовании дополнительной функции, такой как частичная, т.е. она должна быть встроена в мою функцию.

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)

1 Ответ

0 голосов
/ 14 марта 2019

Я пришел с небольшим сценарием для моего личного использования.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...