python3中@dataclasses.dataclass如何用python2适配
时间: 2024-03-09 14:44:35 浏览: 173
在 Python 2 中,我们不能使用 `@dataclasses.dataclass` 装饰器,因为该装饰器是在 Python 3.7 中引入的。但是,我们可以使用 Python 2 中的 `namedtuple` 来实现类似的功能。
下面是一个使用 `namedtuple` 实现类似 `dataclass` 的例子:
```python
from collections import namedtuple
def dataclass(cls):
fields = list(cls.__annotations__)
defaults = {k: v for k, v in cls.__dict__.items() if isinstance(v, tuple)}
TupleClass = namedtuple(cls.__name__, fields)
def __new__(cls, *args, **kwargs):
if args and kwargs:
raise TypeError('Constructor of %r cannot accept both positional and keyword arguments' % (cls.__name__,))
field_values = []
for i, arg in enumerate(args):
if i >= len(fields):
raise TypeError('%s has too many arguments' % (cls.__name__,))
field_values.append(arg)
for k, v in kwargs.items():
i = fields.index(k)
if i >= len(fields):
raise TypeError('%s got an unexpected keyword argument %r' % (cls.__name__, k))
if i < len(args) and args[i] is not None:
raise TypeError('%s got multiple values for argument %r' % (cls.__name__, k))
field_values.append(v)
for i, default in enumerate(defaults.get(k, None) for k in fields[len(field_values):]):
if default is not None:
field_values.append(default)
else:
if i == 0:
raise TypeError('%s missing %d required argument: %r' % (cls.__name__, len(fields) - len(field_values), fields[len(field_values)]))
else:
raise TypeError('%s missing %d required arguments: %r' % (cls.__name__, len(fields) - len(field_values), fields[len(field_values):]))
return TupleClass(*field_values)
setattr(cls, '__new__', __new__)
return cls
```
使用方法与 `@dataclasses.dataclass` 相同,例如:
```python
@dataclass
class Person:
name: str
age: int
gender: str = 'unknown'
p = Person('John', 30)
print(p.name) # John
print(p.age) # 30
print(p.gender) # unknown
```
阅读全文