繁体   English   中英

Python / PyCharm的__slots__类型注释

[英]__slots__ type annotations for Python / PyCharm

如何为通过__slots__定义的属性提供类型注释? 例如:

class DiffMatch:
  __slots__ = ["ref_seq_idx", "ref_txt", "hyp_txt", "start_time", "end_time"]

  def __repr__(self):
    return "%s(%s)" % (self.__class__.__name__, ", ".join(["%s=%r" % (a, getattr(self, a)) for a in self.__slots__]))

(如果可能,Python 2可以在注释中兼容(否则,仅Python 3可以使用),并且PyCharm可以处理它(实际上,这对我现在最重要)。)

__slots__仅告诉type()对象为潜在的属性腾出空间。 列表中的名称本身不是属性 您所拥有的只是一堆描述符。 没有值,所以没有类型。

因此,您需要创建实际属性,并且这些属性具有用于类型注释的所有常规选项。

对于Python 3.6及更高版本,请使用变量类型注释

class DiffMatch:
    __slots__ = ["ref_seq_idx", "ref_txt", "hyp_txt", "start_time", "end_time"]

    ref_seq_idx: int
    # ...

或对于3.6之前的版本(包括Python 2),您必须在可以设置属性的方法上注释类型。 否则,不提供任何实际实例属性支持。 您可以为此添加一个虚拟方法:

class DiffMatch:
    __slots__ = ["ref_seq_idx", "ref_txt", "hyp_txt", "start_time", "end_time"]

    def __type_hints__(self, ref_seq_idx, ...):
        """Dummy method to annotate the instance attribute types
        # type: (int, ...) -> None
        """
        self.ref_seq_idx = ref_seq_idx
        # ...

其中每个参数的所有类型都在文档字符串中列出。 如果您的类具有__init__方法,并且也涉及所有属性,则不需要虚拟方法。

请注意,您无法为这些设置类的默认值,这意味着您不能使用ref_seq_idx = None # type: int (Python 3.6之前的版本)或ref_seq_idx: int = None (Python 3.6及更高版本); __slots__名称将转换为类上的描述符对象,因此名称已设置。

最后但并非最不重要的一点,我将认真研究attrs为您构建这些类型。 最近对该库的支持已添加到PyCharm 2018.2中 ,因此会自动获取类型信息:

@attr.s(slots=True)
class DiffMatch:
    ref_seq_idx = attr.ib(init=False)  # type: int
    # ...

您将免费生成__repr__方法。 init=False注释指示attrs请勿在__init__包含该名称,此时实例在实例化时根本不会设置该属性。

我现在的解决方案:

class DiffMatch:
  __slots__ = ["ref_seq_idx", "ref_txt", "hyp_txt", "start_time", "end_time"]

  def __init__(self):
    self.ref_seq_idx = None  # type: int
    self.ref_txt = None  # type: str
    self.hyp_txt = None  # type: str
    self.start_time = None  # type: Decimal
    self.end_time = None  # type: Decimal

  def __repr__(self):
    return "%s(%s)" % (self.__class__.__name__, ", ".join(["%s=%r" % (a, getattr(self, a)) for a in self.__slots__]))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM