关于python:在脚本中检索可用函数(相同顺序)

Retrieving available functions in script (same order)

我正在清理一些污损的数据,我想让它们自动化一点。也就是说,我希望一个脚本具有一些预定义的清理函数,以便按照清理数据的顺序排列,并且我设计了一个装饰器,使用此解决方案从脚本中检索这些函数:

1
2
3
from inspect import getmembers, isfunction
import cd # cleaning module
functions_list = [o[0] for o in getmembers(cd) if isfunction(o[1])]

这个效果非常好。但是,它确实以不同的顺序检索函数(按名称)

为了重现性的目的,考虑以下清洗模块为cd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def clean_1():
    pass


def clean_2():
    pass


def clean_4():
    pass


def clean_3():
    pass

解决方案输出:

1
['clean_1', 'clean_2', 'clean_3', 'clean_4']

如果需要:

1
['clean_1', 'clean_2', 'clean_4', 'clean_3']

对主要问题的其他解决方案是可以接受的(尽管考虑了性能)。


你已经走到一半了。您只需要根据函数代码对象的第一行对列表进行排序(:inspect-inspect-live-object s)。

请注意,我只在(琐碎的)示例上尝试过这个问题(没有做任何性能测试)。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python3

import sys
from inspect import getmembers, isfunction
import cd  # The module from the question that contains the 4 clean_* functions


def main():
    member_functions = (item for item in getmembers(cd) if isfunction(item[1]))
    function_names = (item[0] for item in sorted(member_functions, key=lambda x: x[1].__code__.co_firstlineno))
    print(list(function_names))


if __name__ =="__main__":
    print("Python {:s} on {:s}
"
.format(sys.version, sys.platform))
    main()

输出:

1
2
3
4
e:\Work\Dev\StackOverflow\q054521087>"e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" code.py
Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32

['clean_1', 'clean_2', 'clean_4', 'clean_3']

Other solutions to the main problem are acceptable (performance is considered though).

为了能够定义和导入助手函数而不自动包含它们,显式列表如何:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def clean_1():
    pass


def clean_2():
    pass


def clean_4():
    pass


def clean_3():
    pass


cleaners = [
    clean_1,
    clean_2,
    clean_4,
    clean_3,
]

或显式修饰器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cleaners = []
cleaner = cleaners.append


@cleaner
def clean_1():
    pass


@cleaner
def clean_2():
    pass


@cleaner
def clean_4():
    pass


@cleaner
def clean_3():
    pass

不过,只要按顺序获取常规模块的属性,就应该能够在python 3.7+中使用__dict__

1
functions_list = [k for k, v in cd.__dict__.items() if isfunction(v)]