Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在没有服务器的情况下使用pydoc将模块索引写入文件_Python_Documentation_Pydoc - Fatal编程技术网

Python 在没有服务器的情况下使用pydoc将模块索引写入文件

Python 在没有服务器的情况下使用pydoc将模块索引写入文件,python,documentation,pydoc,Python,Documentation,Pydoc,目前,我使用以下命令为Python库编写文档: python -m pydoc -w "\\myserver.com\my_library" 这很好,我在my_库HTML文件中找到了从类/方法/函数docstring派生的文档。这甚至记录了在子文件夹中找到的Python文件 我现在想创建并保存一个索引,它可以访问所有这些文件 pydoc文档说,如果启动服务器,这是可能的: pydoc-b将启动服务器并另外打开一个web浏览器 模块索引页。每个服务页面的顶部都有一个导航栏 在可以获得单个项目帮助

目前,我使用以下命令为Python库编写文档:

python -m pydoc -w "\\myserver.com\my_library"
这很好,我在
my_库
HTML文件中找到了从类/方法/函数docstring派生的文档。这甚至记录了在子文件夹中找到的Python文件

我现在想创建并保存一个索引,它可以访问所有这些文件

pydoc
文档说,如果启动服务器,这是可能的:

pydoc-b将启动服务器并另外打开一个web浏览器 模块索引页。每个服务页面的顶部都有一个导航栏 在可以获得单个项目帮助的地方,使用搜索所有模块 在他们的大纲行中输入关键字,然后转到模块索引,主题 和关键词页面

但是,我希望在没有服务器解决方案的情况下编写一个模块索引页,包括到单个文件文档的相对链接。然后,我可以将索引+单个文件[每个py文件一个]存储在用户可以访问的目录中

这是可能的,还是有更好的方法来解决这个问题


我已经看过Sphinx,但对于我的要求来说,这似乎有些过分。

这基本上可以通过运行一个小脚本来实现:

  • 导入要记录的模块

  • 将文档写入html文件,然后

  • 将动态生成index.html的内部函数的输出写入index.html文件

这不是一个非常好的解决方案,因为它依赖于
pydoc
模块的内部结构,但相当紧凑:

import pydoc
import importlib

module_list = ['sys']
for m in module_list:
    importlib.import_module(m)
    pydoc.writedoc(m)

#the monkey patching optionally goes here

with open('index.html','w') as out_file:
    out_file.write(pydoc._url_handler('index.html'))
还有一个缺陷是,它还创建了指向所有内置模块的链接,等等。我们没有(我猜也不想)为这些模块生成文档

我们是否可以从创建index.html文件的
pydoc.py
复制函数,并将其修改为仅为所需模块添加链接?不幸的是,这并不是直截了当的,因为函数使用一些非局部范围来实现它的一些逻辑

下一个最好的解决方案是对生成此页面的
index\u html()
方法进行修补,以便只列出我们的模块

不幸的是,
pydoc.\u url\u handler
使用一个本地函数来实现它,而不是类方法。所以从这里开始就有点棘手了

monkey patch有一个解决方案,但它有点像黑客:

在调用
\u url\u处理程序之前,我们需要:

  • 定义一个补丁版本,该版本只为模块列表中的元素生成链接(使用通过
    \uuuuu占位符\uuuu
    的迂回,因为模块列表未在函数运行的范围内定义,所以我们需要做一些与函数硬编码相对应的事情,比如)

  • 修补
    pydoc
    模块的源代码,以使用该本地函数而不是最初定义的函数

这是通过以下方式实现的:

import inspect, ast

__placeholder__ = None

#our patched version, needs to have same name and signature as original
def html_index():
    """Module Index page."""
    names= __placeholder__

    def bltinlink(name):
        return '<a href="%s.html">%s</a>' % (name, name)

    heading = html.heading(
        '<big><big><strong>Index of Modules</strong></big></big>',
        '#ffffff', '#7799ee')
    contents = html.multicolumn(names, bltinlink)
    contents = [heading, '<p>' + html.bigsection(
        'Module List', '#ffffff', '#ee77aa', contents)]

    contents.append(
        '<p align=right><font color="#909090" face="helvetica,'
        'arial"><strong>pydoc</strong> by Ka-Ping Yee'
        '&lt;ping@lfw.org&gt;</font>')
    return 'Index of Modules', ''.join(contents)

#get source and replace __placeholder__ with our module_list
s=inspect.getsource(html_index).replace('__placeholder__', str(module_list))

#create abstract syntax tree, and store the actual function definition in l_index
l_index=ast.parse(s).body[0]
#ast.dump(l_index) #check if you want

#now obtain source from unpatched pydoc, generate ast patch it and recompile:
s= inspect.getsource(pydoc)
m = ast.parse(s)

def find_named_el_ind(body, name):
    '''find named element in ast body'''
    found=False
    for i,e in enumerate(body):
        if hasattr(e,'name') and e.name == name:
            found=True
            break
    if not found: raise ValueError('not found!')
    return i

#find and replace html_index with our patched html_index
i_url_handler = find_named_el_ind(m.body, '_url_handler')
i_html_index = find_named_el_ind(m.body[i_url_handler].body, 'html_index')
m.body[i_url_handler].body[i_html_index] = l_index

#compile and replace module in memory
co = compile(m, '<string>', 'exec')
exec(co, pydoc.__dict__)

#ast.dump(m.body[i_url_handler]) #check ast if you will
导入检查,ast __占位符\无 #我们的补丁版本,需要有相同的名称和原始签名 def html_index(): “”“模块索引页。”“” 名称=\占位符__ def bltinlink(名称): 返回“”%(名称,名称) heading=html.heading( “模块索引”, "ffffff","7799ee" contents=html.multicolumn(名称,bltinlink) contents=[标题,”+html.bigsection( ‘模块列表’、‘ffffff’、‘ee77aa’,目录)] contents.append( “

pydoc作者:Ka Ping Yee” 'ping@lfw.org') 返回'Index of Modules',''.join(内容) #获取源代码并用模块列表替换占位符 s=inspect.getsource(html\u索引)。替换(“占位符”,str(模块列表)) #创建抽象语法树,并将实际函数定义存储在l_索引中 l_index=ast.parse.body[0] #ast.dump(l#u索引)#检查是否需要 #现在从未修补的pydoc获取源代码,生成ast修补程序并重新编译: s=inspect.getsource(pydoc) m=ast.parse(s) def find_named_el_ind(正文,名称): ''在ast正文中查找命名元素'' 发现=错误 对于枚举(正文)中的i,e: 如果hasattr(e,'name')和e.name==name: 找到=真 打破 如果未找到:raise VALUERROR('not found!') 返回i #查找html_索引并将其替换为修补的html_索引 i_url_handler=find_named_el_ind(m.body,“_url_handler”) i_html_index=find_named_el_ind(m.body[i_url\u handler].body'html_index') m、 body[i\u url\u handler]。body[i\u html\u index]=l\u index #编译并替换内存中的模块 co=编译(m,,'exec') 执行官(公司,pydoc.董事会) #ast.dump(m.body[i_url_handler])#如果愿意,请检查ast


这基本上可以通过运行一个小脚本来实现:

  • 导入要记录的模块

  • 将文档写入html文件,然后

  • 将动态生成index.html的内部函数的输出写入index.html文件

这不是一个非常好的解决方案,因为它依赖于
pydoc
模块的内部结构,但相当紧凑:

import pydoc
import importlib

module_list = ['sys']
for m in module_list:
    importlib.import_module(m)
    pydoc.writedoc(m)

#the monkey patching optionally goes here

with open('index.html','w') as out_file:
    out_file.write(pydoc._url_handler('index.html'))
还有一个缺陷是,它还创建了指向所有内置模块的链接,等等。我们没有(我猜也不想)为这些模块生成文档

我们是否可以从创建index.html文件的
pydoc.py
复制函数,并将其修改为仅为所需模块添加链接?不幸的是,这并不是直截了当的,因为函数使用一些非局部范围来实现它的一些逻辑

下一个最好的解决方案是对生成此页面的
index\u html()
方法进行修补,以便只列出我们的模块

不幸的是
pydoc.\u url\u handler
使用