首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非图形化输出

非图形化输出
EN

Stack Overflow用户
提问于 2014-12-05 20:23:02
回答 1查看 377关注 0票数 1

我已经开始编写一个小型Python实用程序来缓存函数。可用的缓存工具(lru_cache烧杯)不会检测子函数的更改。

为此,我需要一个调用图。在愈伤图中,杰拉尔德·卡祖巴提供了一个很好的工具。然而,到目前为止,我只知道它输出函数名字符串。我需要的不是函数对象就是函数代码散列。

这两个术语的意思是:让def foo(x): return x,然后foo是函数对象,hash(foo.__code__.co_code)是函数代码哈希。

我所拥有的

你可以看到我有什么这里。但下面是一个很小的例子。我在这个例子中遇到的问题是,我不能再次从函数名(字符串)转到函数定义。我和eval(func)在一起。

所以,我想有两种方法可以解决这个问题:

  1. 适当的pycallgraph.output,或者其他方法,直接从Pycallgraph获得我想要的东西。
  2. function.__name__字符串动态加载函数。
代码语言:javascript
复制
import unittest
from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

class Callgraph:
    def __init__(self, output_file='callgraph.png'):
        self.graphviz = GraphvizOutput()
        self.graphviz.output_file = output_file

    def execute(self, function, *args, **kwargs):
        with PyCallGraph(output=self.graphviz):
            ret = function(*args, **kwargs)

        self.graph = dict()
        for node in self.graphviz.processor.nodes():
            if node.name != '__main__':
                f = eval(node.name)
                self.graph[node.name] = hash(f.__code__.co_code)
        return ret

    def unchanged(self):
        '''Checks each function in the callgraph whether it has changed.
        Returns True if all the function have their original code-hash. False otherwise.
        '''
        for func, codehash in self.graph.iteritems():
            f = eval(func)
            if hash(f.__code__.co_code) != codehash:
                return False
        return True

def func_inner(x):
    return x
def func_outer(x):
    return 2*func_inner(x)

class CallgraphTest(unittest.TestCase):
    def testChanges(self):
        cg = Callgraph()
        y = cg.execute(func_outer, 3)
        self.assertEqual(6, y)
        self.assertTrue(cg.unchanged())
        # Change one of the functions
        def func_inner(x):
            return 3+x
        self.assertFalse(cg.unchanged())
        # Change back!
        def func_inner(x):
            return x
        self.assertTrue(cg.unchanged())


if __name__ == '__main__':
    unittest.main()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-10 11:06:06

我通过使用适当的散列对tracer.py进行修补来解决这个问题。

代码语言:javascript
复制
         # Work out the current function or method
         func_name = code.co_name
+        func_hash = hash(code.co_code)

我正在计算函数名保存的值。稍后,您显然还需要保存该值。我这样做是用字典,其中func_name是键,散列是值。在创建节点的函数中,我将其分配给stat_group中的一个新字段。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27324085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档