能否从Python代码生成序列图?

16

我有大约700行代码。我需要写一份关于这段代码的小文档。在这份文档中,我计划使用一个序列图来解释得更详细一些。就像这样:enter image description here由于我有点懒,我想知道是否有工具可以从代码中生成此图。我不想浪费整个周末来做这个。

有什么想法可以帮助我吗?

谢谢。


可能不太适合在SO上讨论,但可以查看networkx https://networkx.readthedocs.io/en/stable/index.html。或者,如果您想要的话,也可以使用工作流管理器,例如ruffus http://ruffus.readthedocs.io/en/latest/ 或snakemake http://snakemake.readthedocs.io/en/stable/。 - Chris_Rands
3个回答

3
我也在搜索这个主题,发现以下有用的内容: https://github.com/bereal/pyspy 它使用byteplay对字节码进行修补,您可以添加自己的回调函数,在每次调用前和每次调用后执行某些操作。类似于使用sys.settrace编写分析器,但更容易。 好吧,我在问题评论中添加了一些修复方法,因为我无法从这里正确使用git。 您的函数可以将DLS作为文本编写,例如PlantUMLZenUML所需,并使用它来生成您的图表。

这个问题在这里不属于范畴内(“要求我们推荐或寻找书籍、工具、软件库、教程或其他站外资源的问题在Stack Overflow上是不合适的,因为它们往往会吸引有意见的答案和垃圾邮件”),应该被关闭。 - bruno desthuilliers
1
是的,我知道,但我必须承认,我也在 Stack Overflow 上寻求建议,当我找到答案时感到很高兴... :-) - Mayra Delgado

3

这里有一个简单的追踪类以及如何使用它的示例。 在每个想要追踪的函数开头实例化该类。 也可以按照相同的原则进行装饰器,但您需要相应地调整Python帧解析。

class SequenceOn:
   autonumber = True
   init_done = False

def __init__(self,participant=""):

    if not SequenceOn.init_done :
        #activate if requested only once
        if SequenceOn.autonumber: 
            print ("autonumber")

        SequenceOn.init_done = True

    #retrieve callee frame
    callee_frame = sys._getframe(1)

    #method/function name
    self.__funcName = callee_frame.f_code.co_name

    # look for a class name
    if 'self' in callee_frame.f_locals:
        self.__className = callee_frame.f_locals['self'].__class__.__name__
    else:
        self.__className = participant

    #retrieve the caller frame and class name of the caller
    caller_frame = sys._getframe(2)

    if 'self' in caller_frame.f_locals:
        self.__caller = caller_frame.f_locals['self'].__class__.__name__
    else:
        self.__caller = ""

    #print the plantuml message
    activate = "++" if self.__caller != self.__className else ""
    print (f'{self.__caller} -> {self.__className} {activate} :{self.__funcName}')


def __del__(self):
    ''' print the return message upon destruction '''
    if self.__caller != self.__className:
        print (f'{self.__caller} <-- {self.__className} -- ')

def note(self,msg):
    print (f'note over {self.__className}:{msg}')

class SequenceOff:
    ''' empty class allowing to disable the trace by eg doing in the begining of a file:

    Seq = SequenceOn # enable sequence generation
    Seq = SequenceOff # disable sequence generation

    and using seq for tracing instead of SequenceOn
    '''
    def __init__(self,participant=""):
        pass
    def __call__(self,msg):
        pass
    def note(self,msg):
        pass

在下面的示例代码中:
if __name__ == "__main__":

class B:
    def __init__(self):
        pass

    def funcB1(self):
        s = SequenceOn()

    def funcB2(self):
        s = SequenceOn()
        s.note("calling private method")
        self.__funcB22()

    def __funcB22(self):
        s = SequenceOn()

class A:
    def __init__(self):
        pass
    def funcA(self):

        s = SequenceOn()
        b = B()
        b.funcB1()
        b.funcB2()

# simple sequence
a = A()
a.funcA()

您将获得:

autonumber
 -> A ++ :funcA
A -> B ++ :funcB1
A <-- B --
A -> B ++ :funcB2
note over B:calling private method
B -> B  :__funcB22
A <-- B --
 <-- A --

这将生成: 在此输入图像描述


谢谢你的解决方案。但是我想知道是否有一种方法可以从静态Python源代码中生成序列图而不改变它? - Beast

3
在Python中使用Plantuml可能会很有帮助。关于如何安装,请使用以下链接: Python中的PlantUML 文本文件应该如下所示:
Python -> HL : create
activate HL
HL -> LL : run
activate LL
LL -> SLI : exec
activate SLI
SLI --> LL
deactivate SLI
LL --> HL
deactivate LL
HL -> LL : push
activate LL
LL -> SLI : push
activate SLI
SLI --> LL
deactivate SLI
LL --> HL
deactivate LL
HL -> LL : run
activate LL
LL -> SLI : exec
activate SLI
SLI --> LL
deactivate SLI
LL --> HL
deactivate LL
HL -> LL : pop
activate LL
LL -> SLI : pop
activate SLI
SLI --> LL
deactivate SLI
LL --> HL
deactivate LL
HL --> Python
deactivate HL

enter image description here

可以使用Python生成文本,例如,在方法声明后面添加。

注意:请勿删除HTML标记。

print>>sd.txt, "->"+str(self.name)+":className"

这将追加到sd.txt并最终创建png文件,方法是运行以下命令:
python -m plantuml sd.txt

python-UML-sequence-diagram


需要记住的是,它会将您的数据发送到外部服务器。我用测试数据在本地测试过,它可以正常工作,只是我不会将这个特定的用于公司的“机密东西”。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接