如何为python NamedTuple实现“可变”默认args

问题描述 投票:1回答:1

我有一个NamedTuple,其attrs是一个不断变化的变量,它取决于实例被实例化的上下文。举一个最小的例子,应该是

import pandas as pd
import datetime

class Record(NamedTuple):
    """
    Immutable record objects
    """
    data: dict
    timestamp: pd.Timestamp


# initiation
# I want the timestamp to be the current time
record = Record(data={'x': 1}, timestamp=datetime.datetime.now())

上面的代码可以正常工作,但是我不想向用户公开timestamp attr。相反,我想要的是这样的东西,将timestamp设置为default arg,但是在启动时它不会失去其独立性:

import pandas as pd
import datetime
import time

class Record(NamedTuple):
    """
    Immutable record objects
    """
    data: dict
    timestamp: pd.Timestamp = datetime.datetime.now()


# initiation, not producing desired output though
record1 = Record(data={'x': 1})
time.sleep(1)
record2 = Record(data={'x': 1})

# expected 1s apart, but actually are the same
print(record1.timestamp, record2.timestamp)

我希望record.timestamp是启动时间,但显然是类声明的时间,即从一开始就“固定”是不希望的。

最佳做法是什么?

从务实的角度讲,的确如此,将timestamp arg留给外部分配似乎没有什么坏处,但由于代码简洁,我只是想避免使用它。

python namedtuple
1个回答
1
投票

我认为您不能通过命名元组来实现。

如果您想要一个不可变的“种类”数据对象,则可以使用冻结的数据类:

import pandas as pd
import datetime
from dataclasses import dataclass, field
import time

@dataclass(frozen=True)
class Record:
    data: dict
    timestamp: pd.Timestamp = field(default_factory=datetime.datetime.now)

record1 = Record(data={'x': 1})
time.sleep(1)
record2 = Record(data={'x': 1})

print(record1.timestamp, record2.timestamp)
© www.soinside.com 2019 - 2024. All rights reserved.