为什么命名数据类字段“日期”会导致RecursionError?

问题描述

from datetime import date
import dataclasses

@dataclasses.dataclass(frozen=True)
class A:
  date: date = dataclasses.field()
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/dataclasses.py",line 1002,in wrap
    return _process_class(cls,init,repr,eq,order,unsafe_hash,frozen)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/dataclasses.py",line 979,in _process_class
    str(inspect.signature(cls)).replace(' -> None',''))
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/inspect.py",line 3040,in __str__
    formatted = str(param)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/inspect.py",line 2558,in __str__
    formatannotation(self._annotation))
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/inspect.py",line 1199,in formatannotation
    return repr(annotation)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/dataclasses.py",line 249,in __repr__
    return ('Field('
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/dataclasses.py",in __repr__
    return ('Field('
  [PrevIoUs line repeated 491 more times]
RecursionError: maximum recursion depth exceeded

但这可行:

@dataclasses.dataclass(frozen=True)
class A:
  date: date

这也是如此:

@dataclasses.dataclass(frozen=True)
class A:
  date_: date = dataclasses.field()

这是错误还是设计上的错误

解决方法

此:

date: date = dataclasses.field()

不会将date注释为datetime.date。它将date注释为dataclasses.field(),因为注释是在赋值后评估的。 dataclasses并不期望字段将其自身作为其注释,并且您也不希望如此。

使用类似

import datetime
import dataclasses

@dataclasses.dataclass(frozen=True)
class A:
  date: datetime.date = dataclasses.field()