如何使用 Python dataclasses 记录 class 的构造函数?
How do I document a constructor for a class using Python dataclasses?
我有一些现有的 Python 3.6 代码,我想移动到 Python 3.7 数据 类。我有 __init__
方法和很好的文档字符串文档,指定构造函数采用的属性及其类型。
但是,如果我在 3.7 中更改这些 类 以使用新的 Python 数据 类,则构造函数是隐式的。在这种情况下如何提供构造函数文档?我喜欢数据的想法类,但如果我必须放弃清晰的文档才能使用它们,我就不喜欢了。
编辑以澄清我目前正在使用文档字符串
dataclasses 的一个主要优点是它们是自记录的。假设您代码的 reader 知道数据 class 是如何工作的(并且您的属性已适当命名),类型注释的 class 属性应该是构造函数的优秀文档。看官方的这个例子dataclass docs:
@dataclass
class InventoryItem:
'''Class for keeping track of an item in inventory.'''
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
如果您不希望 reader 的代码知道数据class 是如何工作的,那么您可能需要重新考虑使用它们或添加解释或 link在 @dataclass
装饰器之后的内联注释中查看文档。如果你真的需要数据 class 的文档字符串,我建议将构造函数文档字符串放在 class 文档字符串中。对于上面的例子:
'''Class for keeping track of an item in inventory.
Constructor arguments:
:param name: name of the item
:param unit_price: price in USD per unit of the item
:param quantity_on_hand: number of units currently available
'''
the sphinx docs 中描述的拿破仑风格的文档字符串(请参阅 ExampleError
class 以了解他们对它的看法)明确涉及您的案例:
The __init__ method may be documented in either the class level docstring, or as a docstring on the __init__ method itself.
如果你不想要这种行为,你必须 explicitly tell sphinx 构造函数文档字符串和 class 文档字符串不是一回事。
意思是,您可以将构造函数信息粘贴到 class 文档字符串的正文中。
如果您从文档字符串构建文档,这些是可以实现的粒度:
1) 最低限度:
@dataclass
class TestClass:
"""This is a test class for dataclasses.
This is the body of the docstring description.
"""
var_int: int
var_str: str
2)附加构造函数参数说明:
@dataclass
class TestClass:
"""This is a test class for dataclasses.
This is the body of the docstring description.
Args:
var_int (int): An integer.
var_str (str): A string.
"""
var_int: int
var_str: str
3)附加属性说明:
@dataclass
class TestClass:
"""This is a test class for dataclasses.
This is the body of the docstring description.
Attributes:
var_int (int): An integer.
var_str (str): A string.
"""
var_int: int
var_str: str
参数和属性描述当然也可以组合,但是由于数据classes 应该是直接映射,所以我看不出这样做的理由。
在我看来,1) 适用于小型或简单数据 classes -- 它已经包含了构造函数签名及其各自的类型,这已经足够了对于一个数据class。如果您想详细说明每个属性,3) 将是最好的选择。
我认为最简单的方法是:
@dataclass
class TestClass:
"""This is a test class for dataclasses.
This is the body of the docstring description.
"""
var_int: int #: An integer.
#: A string.
#: (Able to have multiple lines.)
var_str: str
var_float: float
"""A float. (Able to have multiple lines.)"""
不确定为什么@Arne 呈现的结果看起来像那样。在我的例子中,数据类中的属性将始终显示,而不管文档字符串如何。即:
1) 最低限度:
2)附加构造函数参数说明:
3)附加属性说明:
可能是因为我在 conf.py
(Sphinx v3.4.3, Python 3.7) 中设置了错误:
extensions = [
"sphinx.ext.napoleon",
"sphinx.ext.autodoc",
"sphinx_autodoc_typehints",
"sphinx.ext.viewcode",
"sphinx.ext.autosectionlabel",
]
# Napoleon settings
napoleon_google_docstring = True
napoleon_include_init_with_doc = True
我有一些现有的 Python 3.6 代码,我想移动到 Python 3.7 数据 类。我有 __init__
方法和很好的文档字符串文档,指定构造函数采用的属性及其类型。
但是,如果我在 3.7 中更改这些 类 以使用新的 Python 数据 类,则构造函数是隐式的。在这种情况下如何提供构造函数文档?我喜欢数据的想法类,但如果我必须放弃清晰的文档才能使用它们,我就不喜欢了。
编辑以澄清我目前正在使用文档字符串
dataclasses 的一个主要优点是它们是自记录的。假设您代码的 reader 知道数据 class 是如何工作的(并且您的属性已适当命名),类型注释的 class 属性应该是构造函数的优秀文档。看官方的这个例子dataclass docs:
@dataclass
class InventoryItem:
'''Class for keeping track of an item in inventory.'''
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
如果您不希望 reader 的代码知道数据class 是如何工作的,那么您可能需要重新考虑使用它们或添加解释或 link在 @dataclass
装饰器之后的内联注释中查看文档。如果你真的需要数据 class 的文档字符串,我建议将构造函数文档字符串放在 class 文档字符串中。对于上面的例子:
'''Class for keeping track of an item in inventory.
Constructor arguments:
:param name: name of the item
:param unit_price: price in USD per unit of the item
:param quantity_on_hand: number of units currently available
'''
the sphinx docs 中描述的拿破仑风格的文档字符串(请参阅 ExampleError
class 以了解他们对它的看法)明确涉及您的案例:
The __init__ method may be documented in either the class level docstring, or as a docstring on the __init__ method itself.
如果你不想要这种行为,你必须 explicitly tell sphinx 构造函数文档字符串和 class 文档字符串不是一回事。
意思是,您可以将构造函数信息粘贴到 class 文档字符串的正文中。
如果您从文档字符串构建文档,这些是可以实现的粒度:
1) 最低限度:
@dataclass
class TestClass:
"""This is a test class for dataclasses.
This is the body of the docstring description.
"""
var_int: int
var_str: str
2)附加构造函数参数说明:
@dataclass
class TestClass:
"""This is a test class for dataclasses.
This is the body of the docstring description.
Args:
var_int (int): An integer.
var_str (str): A string.
"""
var_int: int
var_str: str
3)附加属性说明:
@dataclass
class TestClass:
"""This is a test class for dataclasses.
This is the body of the docstring description.
Attributes:
var_int (int): An integer.
var_str (str): A string.
"""
var_int: int
var_str: str
参数和属性描述当然也可以组合,但是由于数据classes 应该是直接映射,所以我看不出这样做的理由。
在我看来,1) 适用于小型或简单数据 classes -- 它已经包含了构造函数签名及其各自的类型,这已经足够了对于一个数据class。如果您想详细说明每个属性,3) 将是最好的选择。
我认为最简单的方法是:
@dataclass
class TestClass:
"""This is a test class for dataclasses.
This is the body of the docstring description.
"""
var_int: int #: An integer.
#: A string.
#: (Able to have multiple lines.)
var_str: str
var_float: float
"""A float. (Able to have multiple lines.)"""
不确定为什么@Arne 呈现的结果看起来像那样。在我的例子中,数据类中的属性将始终显示,而不管文档字符串如何。即:
1) 最低限度:
2)附加构造函数参数说明:
3)附加属性说明:
可能是因为我在 conf.py
(Sphinx v3.4.3, Python 3.7) 中设置了错误:
extensions = [
"sphinx.ext.napoleon",
"sphinx.ext.autodoc",
"sphinx_autodoc_typehints",
"sphinx.ext.viewcode",
"sphinx.ext.autosectionlabel",
]
# Napoleon settings
napoleon_google_docstring = True
napoleon_include_init_with_doc = True