将文档字符串添加到命名元组?

发布于 2024-08-08 02:45:40 字数 394 浏览 8 评论 0原文

是否可以以简单的方式将文档字符串添加到命名元组中?

我尝试过

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

友欢 2024-08-15 02:45:40

在 Python 3 中,不需要包装器,因为类型的 __doc__ 属性是可写的。

from collections import namedtuple

Point = namedtuple('Point', 'x y')
Point.__doc__ = '''\
A 2-dimensional coordinate

x - the abscissa
y - the ordinate'''

这与标准类定义密切对应,其中文档字符串位于标题后面。

class Point():
    '''A 2-dimensional coordinate

    x - the abscissa
    y - the ordinate'''
    <class code>

这在 Python 2 中不起作用。

AttributeError:“type”对象的属性“__doc__”不可写

In Python 3, no wrapper is needed, as the __doc__ attributes of types is writable.

from collections import namedtuple

Point = namedtuple('Point', 'x y')
Point.__doc__ = '''\
A 2-dimensional coordinate

x - the abscissa
y - the ordinate'''

This closely corresponds to a standard class definition, where the docstring follows the header.

class Point():
    '''A 2-dimensional coordinate

    x - the abscissa
    y - the ordinate'''
    <class code>

This does not work in Python 2.

AttributeError: attribute '__doc__' of 'type' objects is not writable.

絕版丫頭 2024-08-15 02:45:40

通过谷歌发现这个老问题,同时想知道同样的事情。

只是想指出,您可以通过直接从类声明中调用namedtuple()来进一步整理它:

from collections import namedtuple

class Point(namedtuple('Point', 'x y')):
    """Here is the docstring."""

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:

from collections import namedtuple

class Point(namedtuple('Point', 'x y')):
    """Here is the docstring."""
‖放下 2024-08-15 02:45:40

您可以通过围绕 namedtuple 返回的值创建一个简单的空包装类来实现此目的。我创建的文件的内容 (nt.py):

from collections import namedtuple

Point_ = namedtuple("Point", ["x", "y"])

class Point(Point_):
    """ A point in 2d space """
    pass

然后在 Python REPL 中:

>>> print nt.Point.__doc__
 A point in 2d space 

或者您可以这样做:

>>> help(nt.Point)  # which outputs...
Help on class Point in module nt:

class Point(Point)
 |  A point in 2d space
 |  
 |  Method resolution order:
 |      Point
 |      Point
 |      __builtin__.tuple
 |      __builtin__.object
 ...

如果您不喜欢每次都手动执行此操作,那么编写一个 sort- 就很简单了执行此操作的工厂函数:

def NamedTupleWithDocstring(docstring, *ntargs):
    nt = namedtuple(*ntargs)
    class NT(nt):
        __doc__ = docstring
    return NT

Point3D = NamedTupleWithDocstring("A point in 3d space", "Point3d", ["x", "y", "z"])

p3 = Point3D(1,2,3)

print p3.__doc__

输出:

A point in 3d space

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):

from collections import namedtuple

Point_ = namedtuple("Point", ["x", "y"])

class Point(Point_):
    """ A point in 2d space """
    pass

Then in the Python REPL:

>>> print nt.Point.__doc__
 A point in 2d space 

Or you could do:

>>> help(nt.Point)  # which outputs...
Help on class Point in module nt:

class Point(Point)
 |  A point in 2d space
 |  
 |  Method resolution order:
 |      Point
 |      Point
 |      __builtin__.tuple
 |      __builtin__.object
 ...

If you don't like doing that by hand every time, it's trivial to write a sort-of factory function to do this:

def NamedTupleWithDocstring(docstring, *ntargs):
    nt = namedtuple(*ntargs)
    class NT(nt):
        __doc__ = docstring
    return NT

Point3D = NamedTupleWithDocstring("A point in 3d space", "Point3d", ["x", "y", "z"])

p3 = Point3D(1,2,3)

print p3.__doc__

which outputs:

A point in 3d space
一花一树开 2024-08-15 02:45:40

是否可以以简单的方式将文档字符串添加到命名元组?

是的,有几个方面。

子类typing.NamedTuple - Python 3.6+

从Python 3.6开始,我们可以直接使用class定义和typing.NamedTuple,并带有文档字符串(和注释!):

from typing import NamedTuple

class Card(NamedTuple):
    """This is a card type."""
    suit: str
    rank: str

与Python相比2、声明空的__slots__是没有必要的。在 Python 3.8 中,甚至对于子类也没有必要。

请注意,声明 __slots__ 不能为非空!

在 Python 3 中,您还可以轻松地更改命名元组上的文档:

NT = collections.namedtuple('NT', 'foo bar')

NT.__doc__ = """:param str foo: foo name
:param list bar: List of bars to bar"""

这使我们能够在调用它们的帮助时查看它们的意图:

Help on class NT in module __main__:

class NT(builtins.tuple)
 |  :param str foo: foo name
 |  :param list bar: List of bars to bar
...

2 中完成相同任务所遇到的困难相比,这非常简单。

与我们在Python 2

在Python 2中,您需要对

  • namedtuple进行子类化,并
  • 声明__slots__ == ()

声明__slots__此处其他答案忽略的重要部分

如果您不声明 __slots__ - 您可以向实例添加可变的临时属性,从而引入错误。

class Foo(namedtuple('Foo', 'bar')):
    """no __slots__ = ()!!!"""

现在:

>>> f = Foo('bar')
>>> f.bar
'bar'
>>> f.baz = 'what?'
>>> f.__dict__
{'baz': 'what?'}

当访问 __dict__ 时,每个实例都会创建一个单独的 __dict__ (缺少 __slots__ 不会妨碍功能,但元组的轻量性、不变性和声明的属性都是命名元组的重要特征)。

如果您希望命令行上回显的内容为您提供等效的对象,您还需要一个 __repr__ :

NTBase = collections.namedtuple('NTBase', 'foo bar')

class NT(NTBase):
    """
    Individual foo bar, a namedtuple

    :param str foo: foo name
    :param list bar: List of bars to bar
    """
    __slots__ = ()

如果您创建基础,则需要这样的 __repr__ 具有不同名称的namedtuple(就像我们上面使用名称字符串参数'NTBase'所做的那样):

    def __repr__(self):
        return 'NT(foo={0}, bar={1})'.format(
                repr(self.foo), repr(self.bar))

要测试repr,实例化,然后测试传递给eval(repr(实例))

nt = NT('foo', 'bar')
assert eval(repr(nt)) == nt

文档中的示例

文档还给出了这样一个例子,关于__slots__ - 我正在向其中添加我自己的文档字符串:

类 Point(namedtuple('Point', 'x y')):
    """文档字符串添加到这里,而不是原来的"""
    __槽__ = ()
    @财产
    def假设(自身):
        返回 (self.x ** 2 + self.y ** 2) ** 0.5
    def __str__(自身):
        return '点:x=%6.3fy=%6.3f hypert=%6.3f' % (self.x, self.y, self.hypot)

...

上面显示的子类将 __slots__ 设置为空元组。这有帮助
通过阻止创建实例来保持较低的内存需求
字典。

这演示了就地使用(就像这里的另一个答案所建议的那样),但请注意,如果您正在调试,当您查看方法解析顺序时,就地使用可能会变得混乱,这就是我最初建议使用 的原因Base 作为基本namedtuple 的后缀:

>>> Point.mro()
[<class '__main__.Point'>, <class '__main__.Point'>, <type 'tuple'>, <type 'object'>]
                # ^^^^^---------------------^^^^^-- same names!        

为了防止在从使用它的类派生子类时创建__dict__,您还必须在子类中声明它。另请参阅此答案,了解有关使用 __slots__ 的更多注意事项。

Is it possible to add a documentation string to a namedtuple in an easy manner?

Yes, in several ways.

Subclass typing.NamedTuple - Python 3.6+

As of Python 3.6 we can use a class definition with typing.NamedTuple directly, with a docstring (and annotations!):

from typing import NamedTuple

class Card(NamedTuple):
    """This is a card type."""
    suit: str
    rank: str

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:

NT = collections.namedtuple('NT', 'foo bar')

NT.__doc__ = """:param str foo: foo name
:param list bar: List of bars to bar"""

Which allows us to view the intent for them when we call help on them:

Help on class NT in module __main__:

class NT(builtins.tuple)
 |  :param str foo: foo name
 |  :param list bar: List of bars to bar
...

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

  • subclass the namedtuple, and
  • declare __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.

class Foo(namedtuple('Foo', 'bar')):
    """no __slots__ = ()!!!"""

And now:

>>> f = Foo('bar')
>>> f.bar
'bar'
>>> f.baz = 'what?'
>>> f.__dict__
{'baz': 'what?'}

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:

NTBase = collections.namedtuple('NTBase', 'foo bar')

class NT(NTBase):
    """
    Individual foo bar, a namedtuple

    :param str foo: foo name
    :param list bar: List of bars to bar
    """
    __slots__ = ()

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'):

    def __repr__(self):
        return 'NT(foo={0}, bar={1})'.format(
                repr(self.foo), repr(self.bar))

To test the repr, instantiate, then test for equality of a pass to eval(repr(instance))

nt = NT('foo', 'bar')
assert eval(repr(nt)) == nt

Example from the documentation

The docs also give such an example, regarding __slots__ - I'm adding my own docstring to it:

class Point(namedtuple('Point', 'x y')):
    """Docstring added here, not in original"""
    __slots__ = ()
    @property
    def hypot(self):
        return (self.x ** 2 + self.y ** 2) ** 0.5
    def __str__(self):
        return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

...

The subclass shown above sets __slots__ to an empty tuple. This helps
keep memory requirements low by preventing the creation of instance
dictionaries.

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:

>>> Point.mro()
[<class '__main__.Point'>, <class '__main__.Point'>, <type 'tuple'>, <type 'object'>]
                # ^^^^^---------------------^^^^^-- same names!        

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__.

年少掌心 2024-08-15 02:45:40

从 Python 3.5 开始,namedtuple 对象的文档字符串可以更新。

来自 whatsnew

Point = nametuple('Point', ['x', 'y'])
Point.__doc__ += ': 笛卡尔坐标'
Point.x.__doc__ = '横坐标'
Point.y.__doc__ = '纵坐标'

Since Python 3.5, docstrings for namedtuple objects can be updated.

From the whatsnew:

Point = namedtuple('Point', ['x', 'y'])
Point.__doc__ += ': Cartesian coodinate'
Point.x.__doc__ = 'abscissa'
Point.y.__doc__ = 'ordinate'
也只是曾经 2024-08-15 02:45:40

在 Python 3.6+ 中,您可以使用:

class Point(NamedTuple):
    """
    A point in 2D space
    """
    x: float
    y: float

In Python 3.6+ you can use:

class Point(NamedTuple):
    """
    A point in 2D space
    """
    x: float
    y: float
清泪尽 2024-08-15 02:45:40

不需要按照接受的答案的建议使用包装类。简单地添加文档字符串:

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
Point.__doc__="A point in 2D space"

这会导致:(使用ipython3的示例):

In [1]: Point?
Type:       type
String Form:<class '__main__.Point'>
Docstring:  A point in 2D space

In [2]: 

Voilà!

No need to use a wrapper class as suggested by the accepted answer. Simply literally add a docstring:

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
Point.__doc__="A point in 2D space"

This results in: (example using ipython3):

In [1]: Point?
Type:       type
String Form:<class '__main__.Point'>
Docstring:  A point in 2D space

In [2]: 

Voilà!

_蜘蛛 2024-08-15 02:45:40

您可以编写自己版本的 Raymond 的 namedtuple 工厂函数 Hettinger 并添加一个可选的 docstring 参数。  但是,使用与配方中相同的基本技术来定义您自己的工厂函数会更容易,而且可以说更好。无论哪种方式,您最终都会得到可重复使用的东西。

from collections import namedtuple

def my_namedtuple(typename, field_names, verbose=False,
                 rename=False, docstring=''):
    '''Returns a new subclass of namedtuple with the supplied
       docstring appended to the default one.

    >>> Point = my_namedtuple('Point', 'x, y', docstring='A point in 2D space')
    >>> print Point.__doc__
    Point(x, y):  A point in 2D space
    '''
    # create a base class and concatenate its docstring and the one passed
    _base = namedtuple(typename, field_names, verbose, rename)
    _docstring = ''.join([_base.__doc__, ':  ', docstring])

    # fill in template to create a no-op subclass with the combined docstring
    template = '''class subclass(_base):
        %(_docstring)r
        pass\n''' % locals()

    # execute code string in a temporary namespace
    namespace = dict(_base=_base, _docstring=_docstring)
    try:
        exec template in namespace
    except SyntaxError, e:
        raise SyntaxError(e.message + ':\n' + template)

    return namespace['subclass']  # subclass object created

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.

from collections import namedtuple

def my_namedtuple(typename, field_names, verbose=False,
                 rename=False, docstring=''):
    '''Returns a new subclass of namedtuple with the supplied
       docstring appended to the default one.

    >>> Point = my_namedtuple('Point', 'x, y', docstring='A point in 2D space')
    >>> print Point.__doc__
    Point(x, y):  A point in 2D space
    '''
    # create a base class and concatenate its docstring and the one passed
    _base = namedtuple(typename, field_names, verbose, rename)
    _docstring = ''.join([_base.__doc__, ':  ', docstring])

    # fill in template to create a no-op subclass with the combined docstring
    template = '''class subclass(_base):
        %(_docstring)r
        pass\n''' % locals()

    # execute code string in a temporary namespace
    namespace = dict(_base=_base, _docstring=_docstring)
    try:
        exec template in namespace
    except SyntaxError, e:
        raise SyntaxError(e.message + ':\n' + template)

    return namespace['subclass']  # subclass object created
〗斷ホ乔殘χμё〖 2024-08-15 02:45:40

这是使用 Docstring 记录的 NamedTuple 的一个很好的示例。 (Python 3.6+)在示例下面,您将找到我对为什么这是一个很好的示例的推理。

注意:下面包含 Python 版本信息

from typing import NamedTuple 

class Point(NamedTuple):
    """Defines a point on a 2D Cartesian plane

    Args:
        x: Provide the x-axis location of the Point
        y: Provide the y-axis location of the Point
    """

    x: float
    "The x-coordinate of the point on the Cartesian plane."

    y: float
    "The y-coordinate of the point on the Cartesian plane."

# The below lines are only required if you care about full compatibility
# with Python's help function 
Point.x.__doc__ = "The x-coordinate of the point on the Cartesian plane."
Point.y.__doc__ = "The y-coordinate of the point on the Cartesian plane."

为什么上面的示例很好?

  • 上面示例中的文档字符串是以 Google 样式指南格式编写的,这允许 Visual Studio 的 Intellisense 理解文档字符串。 (我只尝试过使用 Visual Studio Code)
  • Google 样式指南格式的另一个好处是它与 Sphinx 文档生成器兼容。 (请参阅兼容性说明)
  • NamedTuple 的字段(xy)通过类型提示定义其类型。使用 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.html

Here 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

from typing import NamedTuple 

class Point(NamedTuple):
    """Defines a point on a 2D Cartesian plane

    Args:
        x: Provide the x-axis location of the Point
        y: Provide the y-axis location of the Point
    """

    x: float
    "The x-coordinate of the point on the Cartesian plane."

    y: float
    "The y-coordinate of the point on the Cartesian plane."

# The below lines are only required if you care about full compatibility
# with Python's help function 
Point.x.__doc__ = "The x-coordinate of the point on the Cartesian plane."
Point.y.__doc__ = "The y-coordinate of the point on the Cartesian plane."

Why is the above example good?

  • The Docstring in the above example is written in the Google style guide format, which allows Visual Studio's Intellisense to understand the docstring. (I've only tried with Visual Studio Code)
  • The other benefit of the Google style guide format is that it is compatible with the Sphinx Documentation Generator. (See Compatibility notes)
  • The NamedTuple's fields (x and y) 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

漫雪独思 2024-08-15 02:45:40

我创建这个函数是为了快速创建一个命名元组并记录该元组及其每个参数:

from collections import namedtuple


def named_tuple(name, description='', **kwargs):
    """
    A named tuple with docstring documentation of each of its parameters
    :param str name: The named tuple's name
    :param str description: The named tuple's description
    :param kwargs: This named tuple's parameters' data with two different ways to describe said parameters. Format:
        <pre>{
            str: ( # The parameter's name
                str, # The parameter's type
                str # The parameter's description
            ),
            str: str, # The parameter's name: the parameter's description
            ... # Any other parameters
        }</pre>
    :return: collections.namedtuple
    """
    parameter_names = list(kwargs.keys())

    result = namedtuple(name, ' '.join(parameter_names))

    # If there are any parameters provided (such that this is not an empty named tuple)
    if len(parameter_names):
        # Add line spacing before describing this named tuple's parameters
        if description is not '':
            description += "\n"

        # Go through each parameter provided and add it to the named tuple's docstring description
        for parameter_name in parameter_names:
            parameter_data = kwargs[parameter_name]

            # Determine whether parameter type is included along with the description or
            # if only a description was provided
            parameter_type = ''
            if isinstance(parameter_data, str):
                parameter_description = parameter_data
            else:
                parameter_type, parameter_description = parameter_data

            description += "\n:param {type}{name}: {description}".format(
                type=parameter_type + ' ' if parameter_type else '',
                name=parameter_name,
                description=parameter_description
            )

            # Change the docstring specific to this parameter
            getattr(result, parameter_name).__doc__ = parameter_description

    # Set the docstring description for the resulting named tuple
    result.__doc__ = description

    return result

然后您可以创建一个新的命名元组:

MyTuple = named_tuple(
    "MyTuple",
    "My named tuple for x,y coordinates",
    x="The x value",
    y="The y value"
)

然后使用您自己的数据实例化所描述的命名元组,即。

t = MyTuple(4, 8)
print(t) # prints: MyTuple(x=4, y=8)

当通过 python3 命令行执行 help(MyTuple) 时,将显示以下内容:

Help on class MyTuple:

class MyTuple(builtins.tuple)
 |  MyTuple(x, y)
 |
 |  My named tuple for x,y coordinates
 |
 |  :param x: The x value
 |  :param y: The y value
 |
 |  Method resolution order:
 |      MyTuple
 |      builtins.tuple
 |      builtins.object
 |
 |  Methods defined here:
 |
 |  __getnewargs__(self)
 |      Return self as a plain tuple.  Used by copy and pickle.
 |
 |  __repr__(self)
 |      Return a nicely formatted representation string
 |
 |  _asdict(self)
 |      Return a new OrderedDict which maps field names to their values.
 |
 |  _replace(_self, **kwds)
 |      Return a new MyTuple object replacing specified fields with new values
 |
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |
 |  _make(iterable) from builtins.type
 |      Make a new MyTuple object from a sequence or iterable
 |
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |
 |  __new__(_cls, x, y)
 |      Create new instance of MyTuple(x, y)
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  x
 |      The x value
 |
 |  y
 |      The y value
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  _fields = ('x', 'y')
 |  
 |  _fields_defaults = {}
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from builtins.tuple:
 |  
 |  __add__(self, value, /)
 |      Return self+value.
 |  
 |  __contains__(self, key, /)
 |      Return key in self.
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(self, key, /)
 |      Return self[key].
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __hash__(self, /)
 |      Return hash(self).
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __mul__(self, value, /)
 |      Return self*value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __rmul__(self, value, /)
 |      Return value*self.
 |  
 |  count(self, value, /)
 |      Return number of occurrences of value.
 |  
 |  index(self, value, start=0, stop=9223372036854775807, /)
 |      Return first index of value.
 |      
 |      Raises ValueError if the value is not present.

或者,您也可以通过以下方式指定参数的类型:

MyTuple = named_tuple(
    "MyTuple",
    "My named tuple for x,y coordinates",
    x=("int", "The x value"),
    y=("int", "The y value")
)

I created this function to quickly create a named tuple and document the tuple along with each of its parameters:

from collections import namedtuple


def named_tuple(name, description='', **kwargs):
    """
    A named tuple with docstring documentation of each of its parameters
    :param str name: The named tuple's name
    :param str description: The named tuple's description
    :param kwargs: This named tuple's parameters' data with two different ways to describe said parameters. Format:
        <pre>{
            str: ( # The parameter's name
                str, # The parameter's type
                str # The parameter's description
            ),
            str: str, # The parameter's name: the parameter's description
            ... # Any other parameters
        }</pre>
    :return: collections.namedtuple
    """
    parameter_names = list(kwargs.keys())

    result = namedtuple(name, ' '.join(parameter_names))

    # If there are any parameters provided (such that this is not an empty named tuple)
    if len(parameter_names):
        # Add line spacing before describing this named tuple's parameters
        if description is not '':
            description += "\n"

        # Go through each parameter provided and add it to the named tuple's docstring description
        for parameter_name in parameter_names:
            parameter_data = kwargs[parameter_name]

            # Determine whether parameter type is included along with the description or
            # if only a description was provided
            parameter_type = ''
            if isinstance(parameter_data, str):
                parameter_description = parameter_data
            else:
                parameter_type, parameter_description = parameter_data

            description += "\n:param {type}{name}: {description}".format(
                type=parameter_type + ' ' if parameter_type else '',
                name=parameter_name,
                description=parameter_description
            )

            # Change the docstring specific to this parameter
            getattr(result, parameter_name).__doc__ = parameter_description

    # Set the docstring description for the resulting named tuple
    result.__doc__ = description

    return result

You can then create a new named tuple:

MyTuple = named_tuple(
    "MyTuple",
    "My named tuple for x,y coordinates",
    x="The x value",
    y="The y value"
)

Then instantiate the described named tuple with your own data, ie.

t = MyTuple(4, 8)
print(t) # prints: MyTuple(x=4, y=8)

When executing help(MyTuple) via the python3 command line the following is shown:

Help on class MyTuple:

class MyTuple(builtins.tuple)
 |  MyTuple(x, y)
 |
 |  My named tuple for x,y coordinates
 |
 |  :param x: The x value
 |  :param y: The y value
 |
 |  Method resolution order:
 |      MyTuple
 |      builtins.tuple
 |      builtins.object
 |
 |  Methods defined here:
 |
 |  __getnewargs__(self)
 |      Return self as a plain tuple.  Used by copy and pickle.
 |
 |  __repr__(self)
 |      Return a nicely formatted representation string
 |
 |  _asdict(self)
 |      Return a new OrderedDict which maps field names to their values.
 |
 |  _replace(_self, **kwds)
 |      Return a new MyTuple object replacing specified fields with new values
 |
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |
 |  _make(iterable) from builtins.type
 |      Make a new MyTuple object from a sequence or iterable
 |
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |
 |  __new__(_cls, x, y)
 |      Create new instance of MyTuple(x, y)
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  x
 |      The x value
 |
 |  y
 |      The y value
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  _fields = ('x', 'y')
 |  
 |  _fields_defaults = {}
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from builtins.tuple:
 |  
 |  __add__(self, value, /)
 |      Return self+value.
 |  
 |  __contains__(self, key, /)
 |      Return key in self.
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(self, key, /)
 |      Return self[key].
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __hash__(self, /)
 |      Return hash(self).
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __mul__(self, value, /)
 |      Return self*value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __rmul__(self, value, /)
 |      Return value*self.
 |  
 |  count(self, value, /)
 |      Return number of occurrences of value.
 |  
 |  index(self, value, start=0, stop=9223372036854775807, /)
 |      Return first index of value.
 |      
 |      Raises ValueError if the value is not present.

Alternatively, you can also specify the parameter's type via:

MyTuple = named_tuple(
    "MyTuple",
    "My named tuple for x,y coordinates",
    x=("int", "The x value"),
    y=("int", "The y value")
)
风渺 2024-08-15 02:45:40

不可以,您只能将文档字符串添加到模块、类和函数(包括方法)

No, you can only add doc strings to modules, classes and function (including methods)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文