hhp*_*ram 9 python conventions instance-variables type-hinting python-3.x
不确定类型提示实例变量的Python约定 - 我一直在__init__构造函数参数中执行它们,如下所示:
class LoggedVar(Generic[T]):
def __init__(self, value: T, name: str, logger: Logger) -> None:
self.name = name
self.logger = logger
self.value = value`
Run Code Online (Sandbox Code Playgroud)
链接到上面的代码段:https://docs.python.org/3/library/typing.html#user-defined-generic-types
但我也看到PEP约定注释实例变量(下面的代码段),然后在__init__参数中进行类型提示:
class BasicStarship:
captain: str = 'Picard' # instance variable with default
damage: int # instance variable without default
stats: ClassVar[Dict[str, int]] = {} # class variable`
def __init__(self, damage: int, captain: str = None):
self.damage = damage
if captain:
self.captain = captain # Else keep the default
Run Code Online (Sandbox Code Playgroud)
最后,在PEP526文章的后面,他们说为了方便和惯例,可以做以下事情:
class Box(Generic[T]):
def __init__(self, content):
self.content: T = content
Run Code Online (Sandbox Code Playgroud)
url以上两个代码片段:https: //www.python.org/dev/peps/pep-0526/#class-and-instance-variable-annotations
那么这些约定中的一个是否比我应该坚持的更好/更广泛接受(更好的可读性等......)?
Gar*_*ary 15
@阿萨拉
似乎从 Python 3.8.10 / Mypy 0.910(2021 年 9 月)开始,当谈到区分类定义中实例变量的类型注释和类定义中类(静态)变量的声明时,分配默认值会产生很大的差异。如果您不指定默认值(例如x: int),Python 会将表达式视为类型注释;如果指定默认值(例如x: int = 42),Python 会将表达式视为类(静态)变量声明。
可以使用ClassVar语法为类定义中的类(静态)变量创建类型注释。如果您不指定默认值(例如),则不会创建y: ClassVar[int]事实类(静态)变量;如果您指定默认值(例如),则会创建一个事实类(静态)变量。y: ClassVar[int] = 69
Mic*_*x2a 11
我建议使用第一个版本,在__init__大多数情况下,您可以为方法的参数分配类型。
该特定方法具有最少的冗余,同时仍允许类型检查器验证您__init__是否在代码的其他地方正确调用了该方法。
我建议使用第二个或第三个版本,__init__当您的__init__方法变得足够复杂到可以应用以下一项或多项时,您可以在其中明确注释您的字段(内部或外部):
然而,我不清楚是首选第二个版本还是第三个版本——我个人更喜欢第三个版本,因为它在概念上更清晰,并且似乎没有混合实例与类属性的概念,但我不能否认第二个版本看起来更干净。
我在“打字”gitter 频道上询问了这个问题,并得到了 Guido 的以下回复(在你不知道的情况下,他制作了 Python,目前正在研究 mypy 并输入相关内容):
无论哪种方式,似乎都有强烈的意见。我确实更喜欢将属性注释放在类主体中,而不是将它们散布在整个
__init__和其他方法中。我还认为 PEP 526 这将是未来(还有基于类的 NamedTuple 声明和可能的https://github.com/ericvsmith/dataclasses)。
(引用链接)
因此,似乎推荐使用第二个版本而不是第三个版本,并且以这种方式定义类将在将来的某个时候更深入地集成到 Python 语言本身中!
编辑: PEP 557,数据类是最近接受(?),似乎是在赛道上被包括在Python 3.7。