Указание функции для вызова с определенным аргументом без ее выполнения - PullRequest
0 голосов
/ 10 июня 2018

Я пытаюсь закодировать логику для фильтрации кадра данных Pandas.Я хотел бы закодировать логику в виде словаря с именем подгруппы в качестве ключа и функцией фильтрации для подгруппы в качестве значения:

analytics_table_mappings = {
"Jets Fans": BaseFilter.for_jets_fans,
"Patriots Fans": BaseFilter.for_patriots_fans,
...
}

My BaseFilter.for_jets_fans и BaseFilter.for_patriots_fansстатические методы, которые содержат логику для фильтрации моего информационного кадра для каждой группы поклонников.

Однако я хотел бы создать функцию BaseFilter.for_team_fans, которая принимает строковый параметр team, чтобы указать, каких поклонников команды фильтровать.for.

Моя текущая попытка состоит в том, чтобы кодировать что-то вроде этого

analytics_table_mappings = {
"Jets Fans": {"func": BaseFilter.for_team_fans, "args": "Jets"},
"Patriots Fans":  {"func": BaseFilter.for_team_fans, "args": "Patriots"},
...
}

Мой вопрос: есть ли более элегантный, менее замысловатый, более понятный способ сделать это? Для контекста, я специалист по данным, и это часть большой модели, которую мне в конечном итоге нужно передать моей инженерной команде для обслуживания и обслуживания.Они попросили меня ограничить количество предметно-ориентированного языка (DSL), чтобы помочь смягчить кривую обучения и повысить удобство сопровождения кода.Мне кажется, что использование

"Jets Fans": {"func": BaseFilter.for_team_fans, "args": "Jets"},
"Patriots Fans":  {"func": BaseFilter.for_team_fans, "args": "Patriots"}, 

может быстро превратиться в очень сложный и неуправляемый DSL.Причина, по которой я кодирую свою логику фильтрации, заключается в том, что типы метрик, которые мы фильтруем, и то, как мы их фильтруем, вероятно, будут часто развиваться, поэтому вместо жесткого кодирования их в базу кода я разделил логику фильтра наотдельные файлы configurations.py, которые состоят из словарей (то есть. analytics_table_mappings).Таким образом, я хотел бы сохранить гибкость в моей логике фильтра, в то же время делая ее удобной для технического обслуживания.

Добавление:

Мне также нужно уметь обрабатывать случаи, когда нужно передать несколько параметров.Например:

    "Jets Fans": {"func": BaseFilter.for_team_fans, "args": "Jets"},
    "Patriots Fans":  {"func": BaseFilter.for_team_fans, "args": "Patriots"},
"NFC Fans": {"func": BaseFilter.for_team_fans, "args": ["Bears", "Packers", ...]}

Ответы [ 2 ]

0 голосов
/ 10 июня 2018

Можно рассмотреть functools.partialmethod, что позволяет указать любое число args или kwargs:

from functools import partialmethod

mappings = {'Jets Fans': partialmethod(BaseFilter.for_jets_fans, 'Jets'),
            'Patriots Fans': partialmethod(BaseFilter.for_patriots_fans, 'Patriots'),
            'NFC Fans': partialmethod(BaseFilter.for_team_fans, 'Bears', 'Packers')}
0 голосов
/ 10 июня 2018

Если BaseFilter.for_team_fans - общая базовая функция для каждой записи в вашем analytics_table_mappings дикте, то вы можете выделить ее.Поскольку это оставляет только одно свойство, dict может быть уменьшен до простого key: args спаривания, такого как

analytics_table_mappings = {
    "Jets Fans": "Jets",
    "Patriots Fans": "Patriots",
    "NFC Fans": ["Bears", "Packers", ...]
}

, и затем может включать логику в простой класс:

class Teams:
    analytics_table_mappings = {
        "Jets Fans": "Jets",
        "Patriots Fans": "Patriots",
        "NFC Fans": ["Bears", "Packers", ...]
    }

    @classmethod
    def get_teams(cls, fan_type):
        if fan_type not in cls.analytics_table_mappings:
            return 'Invalid fan type: {}'.format(fan_type)
        teams = cls.analytics_table_mappings[fan_type]
        if not isinstance(teams, list):
            teams = [teams]
        return [cls.for_team_fans(team) for team in teams]

    def for_team_fans(team_name):
        # your logic here
        return team_name


print(Teams().get_teams("Jets Fans"))
>> ['Jets']

print(Teams().get_teams("Patriots Fans"))
>> ['Patriots']

print(Teams().get_teams("NFC Fans"))
>> ['Bears', 'Packers', ...]

print(Teams().get_teams("Argonauts Fans"))
>> Invalid fan type: Argonauts Fans
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...