我想编写一个具有动态创建的文档字符串的python函数.本质上对于一个函数func()我想func.__doc__成为一个调用自定义__get__函数的描述符,根据请求创建docstring.然后help(func)应该返回动态生成的docstring.
这里的上下文是在现有的分析包中编写一个包含大量命令行工具的python包.每个工具都成为一个类似命名的模块函数(通过函数工厂创建并插入到模块命名空间中),通过分析包动态生成函数文档和接口参数.
Ian*_*Ian 11
按照你想要的方式,你无法做你想做的事.
根据您的描述,您似乎可以执行以下操作:
for tool in find_tools():
def __tool(*arg):
validate_args(tool, args)
return execute_tool(tool, args)
__tool.__name__ = tool.name
__tool.__doc__ = compile_docstring(tool)
setattr(module, tool.name, __tool)
Run Code Online (Sandbox Code Playgroud)
即在创建函数时动态创建文档字符串.文档字符串从一次调用到__doc__下一次调用必须是动态的原因吗?
假设有,你必须在一个类中包装你的函数,__call__用来触发动作.
但即便如此,你也遇到了问题.当调用help()来查找docstring时,它会在类而不是实例上调用,所以这样的事情:
class ToolWrapper(object):
def __init__(self, tool):
self.tool = tool
self.__name__ = tool.name
def _get_doc(self):
return compile_docstring(self.tool)
__doc__ = property(_get_doc)
def __call__(self, *args):
validate_args(args)
return execute_tool(tool, args)
Run Code Online (Sandbox Code Playgroud)
不起作用,因为属性是实例,而不是类属性.您可以通过将文档属性放在元类而不是类本身来使其工作
for tool in find_tools():
# Build a custom meta-class to provide __doc__.
class _ToolMetaclass(type):
def _get_doc(self):
return create_docstring(tool)
__doc__ = property(_get_doc)
# Build a callable class to wrap the tool.
class _ToolWrapper(object):
__metaclass__ = _ToolMetaclass
def _get_doc(self):
return create_docstring(tool)
__doc__ = property(_get_doc)
def __call__(self, *args):
validate_args(tool, args)
execute_tool(tool, args)
# Add the tool to the module.
setattr(module, tool.name, _ToolWrapper())
Run Code Online (Sandbox Code Playgroud)
现在你可以做到
help(my_tool_name)
Run Code Online (Sandbox Code Playgroud)
并获取自定义文档字符串,或
my_tool_name.__doc__
Run Code Online (Sandbox Code Playgroud)
为了同样的事情.的__doc__属性是在_ToolWrapper类是需要陷阱后者的情况.