【问题标题】:Python - inspect.getmembers in source code orderPython - 源代码顺序中的inspect.getmembers
【发布时间】:2017-11-02 18:37:35
【问题描述】:

我正在尝试使用 inspect.getmembers 按源代码顺序从模块中获取函数列表。

下面是代码

def get_functions_from_module(app_module):
    list_of_functions = dict(inspect.getmembers(app_module, 
    inspect.isfunction))

    return list_of_functions.values

当前代码不会按照源代码的顺序返回函数对象列表,我想知道是否可以排序。

谢谢!

【问题讨论】:

  • 为什么需要按这个顺序排序?这可能是XY Problem吗?
  • @Bahrom 我需要按顺序遍历模块中的函数列表并将每个函数应用于文件。只有函数按照源代码的顺序才会起作用

标签: python inspect


【解决方案1】:

我想我想出了一个解决方案。

def get_line_number_of_function(func):
    return func.__code__.co_firstlineno

def get_functions_from_module(app_module):
        list_of_functions = dict(inspect.getmembers(app_module, 
        inspect.isfunction))

    return sorted(list_of_functions.values(), key=lambda x:
           get_line_number_of_function(x))

【讨论】:

  • 既然您使用的是inspect,您可以将func.__code__.co_firstlineno 替换为inspect.getsourcelines(func)[1],这样您就可以将其推广到函数之外(例如,也可以添加类)。
【解决方案2】:

您可以使用inspect.findsource 按行号排序。该函数源代码中的文档字符串:

def findsource(object):
    """Return the entire source file and starting line number for an object.
    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a list of all the lines
    in the file and the line number indexes a line in that list.  An OSError
    is raised if the source code cannot be retrieved."""

以下是 Python 2.7 中的示例:

import ab.bc.de.t1 as t1
import inspect


def get_functions_from_module(app_module):
    list_of_functions = inspect.getmembers(app_module, inspect.isfunction)
    return list_of_functions

fns = get_functions_from_module(t1)

def sort_by_line_no(fn):
    fn_name, fn_obj = fn
    source, line_no = inspect.findsource(fn_obj)
    return line_no

for name, fn in sorted(fns, key=sort_by_line_no):
    print name, fn

我的ab.bc.de.t1定义如下:

class B(object):
    def a():
        print 'test'

def c():
    print 'c'

def a():
    print 'a'

def b():
    print 'b'

当我尝试检索排序函数时得到的输出如下:

c <function c at 0x00000000362517B8>
a <function a at 0x0000000036251438>
b <function b at 0x0000000036251668>
>>> 

【讨论】:

  • 谢谢!我也想出了一个解决方案。
  • 酷,点赞。我会留下我的答案作为替代方案,除非我的方法不是一个好主意并且有人指出了这一点。
猜你喜欢
  • 1970-01-01
  • 2010-10-02
  • 2019-05-19
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多