如何将datetime.now()。isoformat()添加到NamedTuple的__init__?

时间:2018-09-06 21:56:46

标签: python datetime namedtuple

我当然尝试过:

class PdfContentRecord(NamedTuple):
    filename: str
    page: int
    cache: dict
    data: dict = dict()
    accessed: str = None

    def __new__(cls, *args, **kwargs):
        self = super().__new__(*args, **kwargs)
        self.accessed = datetime.now().isoformat()
        return self

但是我得到与How to provide additional initialization for a subclass of namedtuple?完全相同的错误

我无法确定attrs是否可以帮助我(太难理解了)。 dataclasses.dataclass可能会有所帮助,但仅支持Python 3.7。

或者我也可以写__slots__ ...

编辑:

  

您是否已阅读所链接问题的答案?

可与from collection import namedtuple一起使用,但不能与from typing import NamedTuple一起使用。

2 个答案:

答案 0 :(得分:2)

Python 3.7+用户应该只利用default_factory中的__post_init__dataclasses钩子。对于使用旧版本Python的用户,请继续阅读。

我认为您应该能够再加上一层类型的内容:

from datetime import datetime
from typing import NamedTuple


class _PdfContentRecord(NamedTuple):
    filename: str
    page: int
    cache: dict
    data: dict = None
    accessed: str = None


class PdfContentRecord(_PdfContentRecord):

    def __new__(cls, filename, page, cache, data=None, accessed=None):
        if data is None:
            data = {}
        if accessed is None:
            accessed = datetime.now().isoformat()
        return super().__new__(cls, filename, page, cache, data, accessed)

但是,可以说,您一开始就失去了使用NamedTuple的一些好处,并且还可以自己编写子类型。

答案 1 :(得分:1)

一个很漂亮的答案,需要pip install attrs(激发dataclass

import attr

@attr.s
class PdfFileRecord:
    name: str = attr.ib()
    type: str = attr.ib()
    cache: dict = attr.ib()
    data: dict = attr.ib(factory=dict)
    accessed: str = attr.ib(factory =lambda: datetime.now().isoformat())

对于dataclass版本,不需要pip,而是at least Python 3.6 is needed

import dataclasses

@dataclasses.dataclass
class PdfFileRecord:
    name: str
    type: str
    cache: dict
    data: dict = dataclasses.field(default_factory =dict)
    accessed: str = dataclases.field(default_factory =lambda: datetime.now().isoformat())