【问题标题】:Retrieving available functions in script (same order)检索脚本中的可用函数(相同顺序)
【发布时间】:2019-06-28 11:39:12
【问题描述】:

我正在清理一些模糊的数据,我想对其进行一些自动化处理。也就是说,我希望一个脚本有一些预定义的清理函数,按照数据清理的顺序排列,我设计了一个装饰器来使用this solution从脚本中检索这些函数:

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

这非常有效。但是,它确实以不同的顺序检索函数 (by name)

出于重现性目的,将以下清洁模块视为cd

def clean_1():
    pass


def clean_2():
    pass


def clean_4():
    pass


def clean_3():
    pass

解决方案输出:

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

它需要在哪里:

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

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

【问题讨论】:

  • 查看 ast 解析python语法树docs.python.org/3/library/ast.html
  • 为清楚起见,您能否包含cd 的代码?在此处的问题中始终包含minimal reproducible example 非常重要。
  • @ChrisLarson。它实际上包括在内。 “出于重现性目的,请考虑以下清洁模块:”
  • @AndrewNaguib 啊。我对您的问题进行了小修改以澄清,以防其他人错过参考。

标签: python python-3.x


【解决方案1】:

你已经成功了一半。您只需根据函数代码对象 ([Python 3]: inspect - Inspect live objects) 的第 1st 行对列表进行排序。

请注意,我只在问题中的 (trivial) 示例上尝试过这个(并且没有进行任何性能测试)。

code.py

#!/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}\n".format(sys.version, sys.platform))
    main()

输出

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']

【讨论】:

    【解决方案2】:

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

    为了能够在不自动包含辅助函数的情况下定义和导入辅助函数,显式列表如何:

    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,
    ]
    

    或显式装饰器:

    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__

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多