将文档字符串添加到命名元组?
是否可以以简单的方式将文档字符串添加到命名元组中?
我尝试过
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
"""
A point in 2D space
"""
# Yet another test
"""
A(nother) point in 2D space
"""
Point2 = namedtuple("Point2", ["x", "y"])
print Point.__doc__ # -> "Point(x, y)"
print Point2.__doc__ # -> "Point2(x, y)"
,但这并不能解决问题。是否可以通过其他方式来做?
Is it possible to add a documentation string to a namedtuple in an easy manner?
I tried
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
"""
A point in 2D space
"""
# Yet another test
"""
A(nother) point in 2D space
"""
Point2 = namedtuple("Point2", ["x", "y"])
print Point.__doc__ # -> "Point(x, y)"
print Point2.__doc__ # -> "Point2(x, y)"
but that doesn't cut it. Is it possible to do in some other way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
在 Python 3 中,不需要包装器,因为类型的 __doc__ 属性是可写的。
这与标准类定义密切对应,其中文档字符串位于标题后面。
这在 Python 2 中不起作用。
AttributeError:“type”对象的属性“__doc__”不可写
。In Python 3, no wrapper is needed, as the
__doc__
attributes of types is writable.This closely corresponds to a standard class definition, where the docstring follows the header.
This does not work in Python 2.
AttributeError: attribute '__doc__' of 'type' objects is not writable
.通过谷歌发现这个老问题,同时想知道同样的事情。
只是想指出,您可以通过直接从类声明中调用namedtuple()来进一步整理它:
Came across this old question via Google while wondering the same thing.
Just wanted to point out that you can tidy it up even more by calling namedtuple() right from the class declaration:
您可以通过围绕
namedtuple
返回的值创建一个简单的空包装类来实现此目的。我创建的文件的内容 (nt.py
):然后在 Python REPL 中:
或者您可以这样做:
如果您不喜欢每次都手动执行此操作,那么编写一个 sort- 就很简单了执行此操作的工厂函数:
输出:
You can achieve this by creating a simple, empty wrapper class around the returned value from
namedtuple
. Contents of a file I created (nt.py
):Then in the Python REPL:
Or you could do:
If you don't like doing that by hand every time, it's trivial to write a sort-of factory function to do this:
which outputs:
是的,有几个方面。
子类typing.NamedTuple - Python 3.6+
从Python 3.6开始,我们可以直接使用
class
定义和typing.NamedTuple
,并带有文档字符串(和注释!):与Python相比2、声明空的
__slots__
是没有必要的。在 Python 3.8 中,甚至对于子类也没有必要。请注意,声明
__slots__
不能为非空!在 Python 3 中,您还可以轻松地更改命名元组上的文档:
这使我们能够在调用它们的帮助时查看它们的意图:
2 中完成相同任务所遇到的困难相比,这非常简单。
与我们在Python 2
在Python 2中,您需要对
__slots__ == ()
声明
__slots__
是此处其他答案忽略的重要部分。如果您不声明 __slots__ - 您可以向实例添加可变的临时属性,从而引入错误。
现在:
当访问
__dict__
时,每个实例都会创建一个单独的__dict__
(缺少__slots__
不会妨碍功能,但元组的轻量性、不变性和声明的属性都是命名元组的重要特征)。如果您希望命令行上回显的内容为您提供等效的对象,您还需要一个 __repr__ :
如果您创建基础,则需要这样的 __repr__ 具有不同名称的namedtuple(就像我们上面使用名称字符串参数
'NTBase'
所做的那样):要测试repr,实例化,然后测试传递给
eval(repr(实例))
文档中的示例
文档还给出了这样一个例子,关于
__slots__
- 我正在向其中添加我自己的文档字符串:这演示了就地使用(就像这里的另一个答案所建议的那样),但请注意,如果您正在调试,当您查看方法解析顺序时,就地使用可能会变得混乱,这就是我最初建议使用
的原因Base
作为基本namedtuple 的后缀:为了防止在从使用它的类派生子类时创建
__dict__
,您还必须在子类中声明它。另请参阅此答案,了解有关使用__slots__
的更多注意事项。Yes, in several ways.
Subclass typing.NamedTuple - Python 3.6+
As of Python 3.6 we can use a
class
definition withtyping.NamedTuple
directly, with a docstring (and annotations!):Compared to Python 2, declaring empty
__slots__
is not necessary. In Python 3.8, it isn't necessary even for subclasses.Note that declaring
__slots__
cannot be non-empty!In Python 3, you can also easily alter the doc on a namedtuple:
Which allows us to view the intent for them when we call help on them:
This is really straightforward compared to the difficulties we have accomplishing the same thing in Python 2.
Python 2
In Python 2, you'll need to
__slots__ == ()
Declaring
__slots__
is an important part that the other answers here miss .If you don't declare
__slots__
- you could add mutable ad-hoc attributes to the instances, introducing bugs.And now:
Each instance will create a separate
__dict__
when__dict__
is accessed (the lack of__slots__
won't otherwise impede the functionality, but the lightweightness of the tuple, immutability, and declared attributes are all important features of namedtuples).You'll also want a
__repr__
, if you want what is echoed on the command line to give you an equivalent object:a
__repr__
like this is needed if you create the base namedtuple with a different name (like we did above with the name string argument,'NTBase'
):To test the repr, instantiate, then test for equality of a pass to
eval(repr(instance))
Example from the documentation
The docs also give such an example, regarding
__slots__
- I'm adding my own docstring to it:This demonstrates in-place usage (like another answer here suggests), but note that the in-place usage may become confusing when you look at the method resolution order, if you're debugging, which is why I originally suggested using
Base
as a suffix for the base namedtuple:To prevent creation of a
__dict__
when subclassing from a class that uses it, you must also declare it in the subclass. See also this answer for more caveats on using__slots__
.从 Python 3.5 开始,
namedtuple
对象的文档字符串可以更新。来自 whatsnew:
Since Python 3.5, docstrings for
namedtuple
objects can be updated.From the whatsnew:
在 Python 3.6+ 中,您可以使用:
In Python 3.6+ you can use:
不需要按照接受的答案的建议使用包装类。简单地添加文档字符串:
这会导致:(使用
ipython3
的示例):Voilà!
No need to use a wrapper class as suggested by the accepted answer. Simply literally add a docstring:
This results in: (example using
ipython3
):Voilà!
您可以编写自己版本的 Raymond 的 namedtuple 工厂函数 Hettinger 并添加一个可选的
docstring
参数。 但是,使用与配方中相同的基本技术来定义您自己的工厂函数会更容易,而且可以说更好。无论哪种方式,您最终都会得到可重复使用的东西。You could concoct your own version of the namedtuple factory function by Raymond Hettinger and add an optional
docstring
argument. However it would be easier -- and arguably better -- to just define your own factory function using the same basic technique as in the recipe. Either way, you'll end up with something reusable.这是使用 Docstring 记录的 NamedTuple 的一个很好的示例。 (Python 3.6+)在示例下面,您将找到我对为什么这是一个很好的示例的推理。
注意:下面包含 Python 版本信息
为什么上面的示例很好?
x
和y
)通过类型提示定义其类型。使用 Typehint 比在文档字符串中嵌入类型信息更可取,因为在使用 PyCharm 或 Visual Studio Code 等现代代码编辑器时,它们提供更好的类型检查器和 IntelliSense 支持。您可以在此处找到有关 Google 样式指南格式的更多信息:https://google.github.io/ styleguide/pyguide.html
兼容性说明
我手动测试/验证了上述代码在Python 3.11中的功能并且文档字符串与 Sphinx 7.2.6 兼容。但是,使用 Sphinx 时,您必须修改
conf.py
文件以确保与 Google Style Docstring 兼容。您可以在此处找到有关 Sphinx 兼容性的更多信息: https://www .sphinx-doc.org/en/master/usage/extensions/napoleon.htmlHere is a good example of a NamedTuple that is documented with a Docstring. (Python 3.6+) Below the example, you will find my reasoning on why this is a good example.
Note: Python version information included below
Why is the above example good?
x
andy
) have their type defined via typehints. Using Typehints is preferable over embedding the type information within a docstring because they provide better type-checker and IntelliSense support when using modern code editors such as PyCharm or Visual Studio Code.You can find more on the Google style guide format here: https://google.github.io/styleguide/pyguide.html
Compatibility Notes
I manually tested/verified that the above code is functional in Python 3.11 and that the docstring is compatible with Sphinx 7.2.6. However, when using Sphinx, you must modify the
conf.py
file to ensure compatibility with Google Style Docstring. You can find more about Sphinx compatibility here: https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html我创建这个函数是为了快速创建一个命名元组并记录该元组及其每个参数:
然后您可以创建一个新的命名元组:
然后使用您自己的数据实例化所描述的命名元组,即。
当通过 python3 命令行执行
help(MyTuple)
时,将显示以下内容:或者,您也可以通过以下方式指定参数的类型:
I created this function to quickly create a named tuple and document the tuple along with each of its parameters:
You can then create a new named tuple:
Then instantiate the described named tuple with your own data, ie.
When executing
help(MyTuple)
via the python3 command line the following is shown:Alternatively, you can also specify the parameter's type via:
不可以,您只能将文档字符串添加到模块、类和函数(包括方法)
No, you can only add doc strings to modules, classes and function (including methods)