代码之家  ›  专栏  ›  技术社区  ›  hhprogram

Python实例变量的类型提示约定

  •  28
  • hhprogram  · 技术社区  · 7 年前

    __init__ 构造函数参数 like seen here

    class LoggedVar(Generic[T]):
        def __init__(self, value: T, name: str, logger: Logger) -> None:
            self.name = name
            self.logger = logger
            self.value = value`
    

    但我也看到了PEP惯例,即注释实例变量(下面的代码段),然后在

    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
    

    最后,在PEP 526文章的后面,他们说为了方便和惯例,可以做以下事情:

    class Box(Generic[T]):
        def __init__(self, content):
            self.content: T = content
    

    here .)

    那么,与我应该坚持的其他约定(更好的可读性等)相比,这些约定之一是否更好/更广泛地被接受?

    3 回复  |  直到 3 年前
        1
  •  13
  •   Michael0x2a    6 年前

    我建议使用第一个版本,您可以将类型分配给 __init__

    该特定方法具有最少的冗余,同时仍然允许类型检查器验证您正在调用该方法 __初始化__

    我建议使用第二个或第三个版本,其中明确注释字段(内部或外部) __初始化__ __初始化__

    1. 参数和字段之间不再存在一对一的映射
    2. 您有复杂的初始化逻辑,模糊了字段的分配方式。

    我在“键入”gitter频道上询问了这个问题,并从Guido那里得到了以下回复(很可能你不知道,他制作了Python,目前正在开发mypy和键入相关的东西):

    不管怎样,似乎都有强烈的意见。我确实更喜欢将属性注释放在类主体中,而不是将它们洒在整个类主体中 和其他方法。我还认为,有了PEP 526,这将是未来的趋势(也有基于类的NamedTuple声明和可能的 https://github.com/ericvsmith/dataclasses

    ( link to quote

    因此,似乎建议使用第二个版本而不是第三个版本,并且在将来的某个时候,以这种方式定义类将更深入地集成到Python语言本身中!

    PEP 557, data classes recently accepted

        2
  •  6
  •   Gary    3 年前

    似乎从Python 3.8.10/Mypy 0.910(2021 9月)开始,在区分类定义中实例变量的类型注释和类定义中类(静态)变量的声明时,默认值的赋值会产生很大的差异。如果您没有指定默认值(例如。, x: int x: int = 42 ),Python将表达式视为类(静态)变量声明。

    可以使用 ClassVar 语法。如果您没有指定默认值(例如。, y: ClassVar[int] 被创建;如果指定默认值(例如。, y: ClassVar[int] = 69 ),一个事实类(静态)变量

        3
  •  2
  •   Alex Waygood MacFreek    3 年前

    LoggedVar

    这个 BasicStarShip 类通过将变量移出 __init__ 作用船长在那里宣布, BasicStarShip.captain 'Picard' .

    PEP 526注释很好阅读,但它是一个特定案例的新规则 作用从 :