Python - 运行流程图, call graph, 调用图

Posted Rocinante

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python - 运行流程图, call graph, 调用图相关的知识,希望对你有一定的参考价值。

解决方案

  1. pycallgraph(感觉直接用pycallgraph grahviz命令生成的图并不是我想要的)
  2. 如何去阅读并学习一些优秀的开源框架的源码? - mailto1587的回答 - 知乎
    https://www.zhihu.com/question/26766601/answer/33952627
  3. traceback(没有图,直接在控制台打印)

解决方案2(用django来示范)

# django里的一个view
# views.py

class ArticleSearchView(View):

    def get(self, request):
        form = SearchForm(request.GET)
        from .utils import cheese    # 在这里插入
        cheese()    # 在这里插入
        if form.is_valid():
            keyword = form.cleaned_data.get("keyword")
            if keyword:
                article_list = Article.objects.filter(title__icontains=keyword)
                return render(request, \'blog/search.html\', {\'form\': form, \'article_list\': article_list})
        else:
            form = SearchForm()
        return render(request, \'blog/search.html\', {\'form\': form, \'article_list\': False, })


# utils.py
from __future__ import unicode_literals

def cheese(frame=None, slient=False):
    import sys
    import tempfile
    import webbrowser
    import pygraphviz as pgv

    if not frame:
        frame = sys._getframe().f_back

    G = pgv.AGraph(strict=False, directed=True)

    stack = []

    node_set = set()
    subgraph_set = {}

    while frame:
        filename = frame.f_code.co_filename
        firstlineno = frame.f_code.co_firstlineno
        function = frame.f_code.co_name

        node = \'{0}:{1}:{2}\'.format(filename, firstlineno, function)
        if node not in node_set:
            node_set.add(node)
            if filename not in subgraph_set:
                subgraph_set[filename] = G.add_subgraph(
                    name=\'cluster\' + filename,
                    label=filename
                )
            subgraph = subgraph_set[filename]
            subgraph.add_node(
                node,
                label=\'{0}:{1}\'.format(firstlineno, function)
            )

        stack.append(frame)
        frame = frame.f_back

    stack.reverse()

    len_stack = len(stack)

    for index, start in enumerate(stack):

        if index + 1 < len_stack:
            start_filename = start.f_code.co_filename
            start_firstlineno = start.f_code.co_firstlineno
            start_function = start.f_code.co_name
            start_lineno = start.f_lineno
            start_subgraph = subgraph_set[start_filename]

            end = stack[index + 1]
            end_filename = end.f_code.co_filename
            end_firstlineno = end.f_code.co_firstlineno
            end_function = end.f_code.co_name
            end_subgraph = subgraph_set[end_filename]

            if index == 0:
                color = \'green\'
            elif index == len_stack - 2:
                color = \'red\'
            else:
                color = \'black\'

            G.add_edge(
                \'{0}:{1}:{2}\'.format(start_filename,
                                     start_firstlineno,
                                     start_function),
                \'{0}:{1}:{2}\'.format(end_filename,
                                     end_firstlineno,
                                     end_function),
                color=color,
                ltail=start_subgraph.name,
                lhead=end_subgraph.name,
                label=\'#{0} at {1}\'.format(index + 1, start_lineno)
            )

    fd, name = tempfile.mkstemp(\'.png\')

    G.draw(name, prog=\'dot\')
    G.close()

    if not slient:
        webbrowser.open(\'file://\' + name)

    return name

解决方案2的结果图

解决方案3(用Flask来示范)

from flask import Flask

app = Flask(__name__)


@app.route(\'/\')
def index():
    import traceback
    traceback.print_stack()
    return \'Yet another hello!\'

if __name__ == \'__main__\':
    app.run()

解决方案3的结果图

以上是关于Python - 运行流程图, call graph, 调用图的主要内容,如果未能解决你的问题,请参考以下文章

将更多/多个参数传递给 Python subprocess.call [重复]

python-flask-wtforms组件流程源码

subprocess.call未按预期运行

python运行后显示Traceback (most recent call last):啥意思?

在python中,为什么mock_calls在调试模式下运行时调用.__ str __()调用的次数不一致?

Python模块学习之特殊函数 __call__ 的使用