且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

获取源脚本详细信息,类似于inspect.getmembers()而不导入脚本

更新时间:2021-08-11 03:25:02

所以我更多地环顾了一下并快速使用这个家伙的答案,以获取每个功能的来源。它还没有接近完美,但如果你感兴趣的话就在这里:

So I looked around some more and quickly Frankenstein'd a solution using this dude's answer to get each function's source. It isn't anywhere near perfect yet, but here it is if you're interested:

import ast
import re
import json


st = open('filename.py').read()
tree = ast.parse(st)
functions_info = {}


def parse(function):
    global st
    global functions_info
    fn_info = {}
    fn_info['Args'] = []
    fn_info['Source'] = []
    fn_info['Callees'] = []

    print(function.name)

    for arg in function.args.args:
        fn_info['Args'].append(arg.arg)

    lastBody = function.body[-1]

    while isinstance (lastBody,(ast.For,ast.While,ast.If)):
        lastBody = lastBody.Body[-1]
    lastLine = lastBody.lineno

    if isinstance(st,str):
        st = st.split("\n")
    for i , line in enumerate(st,1):
        if i in range(function.lineno,lastLine+1):
            # print(line)
            fn_info['Source'].append(line)

    for line in fn_info['Source']:
        if not line.lstrip().startswith('#'):
            fn_pattern = r'(\w+)\('
            match = re.search(fn_pattern, line)
            if match:
                callee = match.group(1)
                fn_info['Callees'].append(callee)

    functions_info[function.name] = fn_info

for obj in tree.body:
    if isinstance(obj, ast.ClassDef):
        for func in obj.body:
            if isinstance(func, (ast.FunctionDef)):
                parse(func)

    if isinstance(obj, ast.FunctionDef):
        parse(obj)

print(json.dumps(functions_info, indent=4))

输出:

{
    "displayWonder": {
        "Source": [
            "    def displayWonder(self):",
            "        return \"Hello \" + str(self.displayGreeting())"
        ],
        "Args": [
            "self"
        ],
        "Callees": []
    },
    "displayGreeting": {
        "Source": [
            "    def displayGreeting(self):",
            "        string = \"Greetings \" + self.myName",
            "        return string"
        ],
        "Args": [
            "self"
        ],
        "Callees": []
    },
    "myStatic": {
        "Source": [
            "    @staticmethod",
            "    def myStatic():",
            "        return \"I am static\""
        ],
        "Args": [],
        "Callees": []
    },
    "displayHello": {
        "Source": [
            "    def displayHello(self):",
            "        return \"Hello \" + self.myName"
        ],
        "Args": [
            "self"
        ],
        "Callees": []
    },
    "__init__": {
        "Source": [
            "    def __init__(self):",
            "        self.myName = 'Wonder?'"
        ],
        "Args": [
            "self"
        ],
        "Callees": []
    },
    "main": {
        "Source": [
            "def main():",
            "    hello = Hello(\"Wonderful!!!\")",
            "    # name = unicode(raw_input(\"Enter name: \"), 'utf8')",
            "    # print(\"User specified:\", name)",
            "    print(hello.displayGreeting())"
        ],
        "Args": [],
        "Callees": []
    }
}