Как вызывать методы Python, используя словарь - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь создать список (или словарь) методов, которые преобразуют данные.Например, у меня есть данные, подобные приведенным ниже:

data = [
{'Result': 1, 'Reason1': False, 'Reason2': 1},
{'Result': 0, 'Reason1': False, 'Reason2':'haha'},
{'Result': 0, 'Reason1': True, 'Reason2': 'hehe'},
{'Result': 0, 'Reason1': True, 'Reason2': 0},
]


def rule_1(datum):
    modified_datum = datum
    if datum['Reason1']:
        modified_datum['Result'] = 1 # always set 'Result' to 1 whenever 'Reason1' is True
    else:
        modified_datum['Result'] = 1 # always set 'Result' to 0 whenever 'Reason1' is False
    return modified_datum


def rule_2(datum):
    modified_datum = datum
    if type(datum['Reason2']) is str:
        modified_datum['Result'] = 1 # always set 'Result' to 1 whenever 'Reason2' is of type 'str'
    elif type(datum['Reason2']) is int:
        modified_datum['Result'] = 2 # always set 'Result' to 2 whenever 'Reason2' is of type 'int'
    else:
        modified_datum['Result'] = 0
    return modified_datum


# There can be 'rule_3', 'rule_4' and so on... Also, these rules may have different method signatures (that is, they may take in more than one input parameter)
rule_book = [rule_2, rule_1] # I want to apply rule_2 first and then rule_1

processed_data = []
for datum in data:
    for rule in rule_book:
        # Like someone mentioned here, the line below works, but what if I want to have different number of input parameters for rule_3, rule_4 etc.?
        # processed_data.append(rule(datum))

Я думаю, этот ответ о переполнении стека довольно близко подходит к тому, что я пытаюсь сделать, но я хотел бы узнатьот людей, которые имеют опыт работы с Python о том, как лучше всего справиться с этим.Я пометил этот пост словом «рассылка», что, по-моему, является термином, к которому он относится, за то, чего я пытаюсь достичь (?) Спасибо заранее за вашу помощь и предложения!

1 Ответ

0 голосов
/ 17 октября 2018

Как прокомментировали, вы довольно близки.Все, что вам нужно сделать, это вызвать rule во время итерации.

Что касается обработки параметров различной длины, вы можете использовать *args и **kwargs в своих правилах.Вот краткий пример:

def rule1(*args, **kwargs):
    # Handling of non-keyword params passed in, if any
    if args:
        for arg in args:
            print(f'{arg} is type {type(arg)}')
    # if kwargs is not necessary if you don't intend to handle keyword params

def rule2(*args, **kwargs):
    # if args is not necessary if you don't intend to handle non-keyword params

    # handling of keyword params passed in, if any
    if kwargs:
        for k, v in kwargs.items():
            print(f'Keyword arg {k} has value {v}')

rule_book = [rule2, rule1]
for rule in rule_book:
    # iterate through the rule_book with the same amount of args and kwargs
    rule('I am a string', 123, ('This', 'is', 'Tuple'), my_list=[0, 1, 2], my_dict={'A': 0, 'B': 1})

Результат:

Keyword arg my_list has value [0, 1, 2]
Keyword arg my_dict has value {'A': 0, 'B': 1}
I am a string is type <class 'str'>
123 is type <class 'int'>
('This', 'is', 'Tuple') is type <class 'tuple'>

Ключ к выводу - сохранить соответствие параметров вашим правилам, как только все будет передано,просто возьмите соответствующий объект и используйте его:

def rule3(*args, **kwargs):
    if args:
        for arg in args:
            if isinstance(arg, tuple):
                # if there's a tuple presented, reverse each of the inner items
                print([a[::-1] for a in arg])

 # ['sihT', 'si', 'elpuT']

Благодаря тому, как вы структурировали свой код, я уверен, что вы сможете понять и применить его к своему собственному.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...