代码之家  ›  专栏  ›  技术社区  ›  Gary van der Merwe

有没有一种方法可以使用数据类、带默认值的字段和带插槽的__

  •  2
  • Gary van der Merwe  · 技术社区  · 6 年前

    我想把 __slots__ 在具有默认字段的数据类上。当我尝试这样做时,我得到这个错误:

    >>> @dataclass
    ... class C:
    ...     __slots__ = ('x', 'y', )
    ...     x: int
    ...     y: int = 1
    ...     
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
    ValueError: 'y' in __slots__ conflicts with class variable
    

    有没有办法做到这一点?

    1 回复  |  直到 6 年前
        1
  •  1
  •   L3viathan gboffi    6 年前

    有,通过使用 @add_slots decorator by ericvsmith :

    import dataclasses
    
    def add_slots(cls):
        # Need to create a new class, since we can't set __slots__
        #  after a class has been created.
    
        # Make sure __slots__ isn't already set.
        if '__slots__' in cls.__dict__:
            raise TypeError(f'{cls.__name__} already specifies __slots__')
    
        # Create a new dict for our new class.
        cls_dict = dict(cls.__dict__)
        field_names = tuple(f.name for f in dataclasses.fields(cls))
        cls_dict['__slots__'] = field_names
        for field_name in field_names:
            # Remove our attributes, if present. They'll still be
            #  available in _MARKER.
            cls_dict.pop(field_name, None)
        # Remove __dict__ itself.
        cls_dict.pop('__dict__', None)
        # And finally create the class.
        qualname = getattr(cls, '__qualname__', None)
        cls = type(cls)(cls.__name__, cls.__bases__, cls_dict)
        if qualname is not None:
            cls.__qualname__ = qualname
        return cls
    

    用途:

    >>> @add_slots
    ... @dataclass
    ... class C:
    ...     __slots__ = ('x', 'y', )
    ...     x: int
    ...     y: int = 1
    

    添加 __slots__ 手动工作只要 没有默认值 . 你可以找到相关的 Github issue here