关于python:如何在将函数名用作字符串时调用它?

How to call a function when using its name as string?

问题陈述:

我试图从数据中读取行,并通过将列表传递给函数来输出forwardreverse方向。为了解决我想做的事情,我必须用管道连接到function-name as string。我在下面做一个模拟测试,以一种简单的方式复制我的原始问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
my_str = 'abcdef
ijklmn
stuv
'

my_str = my_str.rstrip('
'
).split('
'
)

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函数调用

但我似乎解决不了。


以下是评论中已经建议的方法:

1
2
3
4
5
6
7
def orient_my_str(line, preprocessor):
    my_output = ''
    for item in preprocessor(line):
        my_output += item

    print(my_output)
    return my_output

正如我提到的,您可以将函数作为参数传递。要调用它,请执行以下操作:

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

如果不希望显式传递lambda函数,也可以使用preprocessor的默认参数。

总之,重要的一点是不需要传递函数名,这样就可以查找并调用该函数。只需将函数本身作为参数传递。


不要使用eval,保持简单的方法。您不需要复制for以下的任何内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)

输出:

1
2
3
4
4321
1234
4321
1234