Описание проблемы:

Я пытаюсь прочитать строки из моих данных и вывести ориентацию forward и reverse, передав свой список функции. Чтобы решить, что я пытаюсь сделать, я должен передать function-name as string. Я делаю пробный тест ниже, который просто повторяет мою первоначальную проблему.

my_str = 'abcdef\nijklmn\nstuv\n'
my_str = my_str.rstrip('\n').split('\n')

for lines in my_str:
    print(lines)
    line_list = list(lines)

    # I want to read both forward and reverse orientation using a function "(def orient_my_str():"
    # the reason to pass this into another function is because I have lots of data crunching to do in each orientation (not shown here).
    # but, below process typically resolves what I am trying to achieve

    line_rev = orient_my_str(line_list, orientation='reversed')
    line_fwd = orient_my_str(line_list, orientation='')

    print('list in reverse orientation :', line_rev)
    print('list in forward orientation :', line_fwd)
    print()


# I am only want to make one function not two, because if I make two functions ..
# .. I will have to copy a large amount of code below the for-loop.
# there should be a way to fix this problem (calling function using string name when required and not).
def orient_my_str(line, orientation):
    my_output = ''
    for item in eval(orientation)(line):
        my_output += item

    print(my_output)
    return my_output

# But, this only works for reverse orientation. I know the issue is with passing "eval('')(line)" but was hoping it would work.

Я пытался исправить свой код, используя идеи из этих ссылок,

Используйте строку для вызова функции в Python

Вызов функции модуля с использованием его имени (строки)

вызов функции python с переменной

Но я не могу понять это.

-5
everestial007 13 Мар 2018 в 21:57

2 ответа

Лучший ответ

Вот подход, уже предложенный в комментарии:

def orient_my_str(line, preprocessor):
    my_output = ''
    for item in preprocessor(line):
        my_output += item

    print(my_output)
    return my_output

Как я уже говорил, вы можете передать функцию в качестве параметра. Чтобы позвонить, вы делаете это:

line_rev = orient_my_str(line_list, preprocessor=reversed)
line_fwd = orient_my_str(line_list, preprocessor=lambda x: x)

Вы также можете использовать параметр по умолчанию для preprocessor, если вам не нравится явная передача лямбда-функции.

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

2
Ulrich Eckhardt 13 Мар 2018 в 20:16

Не используйте eval, придерживайтесь простых методов. Вам не нужно ничего копировать под for:

def orient_my_str(line, reverse = False): 
    # add any needed preprocessing here, store result as new list
    # and use it in the following line instead of the variable line
    data = reversed(line) if reverse else line 

    my_output = ''
    for item in data: # operate on line or reversed line as needed
        my_output += item

    print(my_output)
    return my_output

line_list= ["1","2","3","4"]
line_rev = orient_my_str(line_list, reverse = True)
line_fwd = orient_my_str(line_list)

print(line_rev)
print(line_fwd)

Выход:

4321
1234
4321
1234
2
Patrick Artner 13 Мар 2018 в 19:25