代码之家  ›  专栏  ›  技术社区  ›  Thom Smith

使用Sphinx AutoDoc的漂亮打印特殊方法

  •  0
  • Thom Smith  · 技术社区  · 7 年前

    Python documentation 特殊方法有不同的记录。例如,而不是 __len__ ,文档显示 len(d) .我怎么能让斯芬克斯也这么做呢?

    似乎我所要做的就是重写产生方法名的逻辑,但我不知道该怎么做。现有的AutoDocs事件似乎不允许这样做。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Thom Smith    7 年前

    正如Deepspace指出的,这不是内置的功能;python文档是手工完成的。

    相反,我写了一个狮身人面像转换:

    from sphinx.transforms import SphinxTransform
    import sphinx.addnodes as SphinxNodes
    
    SPECIAL_METHODS = {
        '__getitem__': '{self}[{0}]',
        '__setitem__': '{self}[{0}] = {1}',
        '__delitem__': 'del {self}[{0}]',
        '__contains__': '{0} in {self}',
    
        '__lt__': '{self} < {0}',
        '__le__': '{self} <= {0}',
        '__eq__': '{self} == {0}',
        '__ne__': '{self} != {0}',
        '__gt__': '{self} > {0}',
        '__ge__': '{self} >= {0}',
    
        '__hash__': 'hash({self})',
        '__len__': 'len({self})',
    
        '__add__': '{self} + {0}',
        '__sub__': '{self} - {0}',
        '__mul__': '{self} * {0}',
        '__matmul__': '{self} @ {0}',
        '__truediv__': '{self} / {0}',
        '__floordiv__': '{self} // {0}',
        '__mod__': '{self} % {0}',
        '__divmod__': 'divmod({self}, {0})',
        '__pow__': '{self} ** {0}',
        '__lshift__': '{self} << {0}',
        '__rshift__': '{self} >> {0}',
        '__and__': '{self} & {0}',
        '__xor__': '{self} ^ {0}',
        '__or__': '{self} | {0}',
    
        '__neg__': '-{self}',
        '__pos__': '+{self}',
        '__abs__': 'abs({self})',
        '__invert__': '~{self}',
    }
    
    class PrettifySpecialMethods(SphinxTransform):
        default_priority = 800
    
        def apply(self):
            methods = (
                sig for sig in self.document.traverse(SphinxNodes.desc_signature)
                if 'class' in sig
            )
    
            for ref in methods:
                name_node = ref.next_node(SphinxNodes.desc_name)
                method_name = name_node.astext()
    
                if method_name in SPECIAL_METHODS:
                    param_names = [ p.astext() for p in ref.traverse(SphinxNodes.desc_parameter) ]
    
                    ref.remove(ref.next_node(SphinxNodes.desc_parameterlist))
    
                    name_node.replace_self(
                        SphinxNodes.desc_name(
                            name_node.source,
                            SPECIAL_METHODS[method_name].format(*param_names, self='d'),
                            **name_node.attributes
                        )
                    )
    

    我还没有彻底测试过这个,它缺少一些特性,但它应该是一个开始(希望对某人有所帮助)。

    推荐文章