【问题标题】:How to implement "varying" default args for python NamedTuple如何为 python NamedTuple 实现“变化”的默认参数
【发布时间】:2019-10-29 15:40:38
【问题描述】:

我有一个NamedTuple,其中一个属性是一个不断变化的变量,该变量取决于初始化实例的上下文。举个最简单的例子,应该是这样的

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】:

    我认为您无法使用命名元组来实现这一点。

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

    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)
    

    【讨论】:

      猜你喜欢
      • 2016-03-12
      • 1970-01-01
      • 2012-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-30
      • 1970-01-01
      • 2012-03-06
      相关资源
      最近更新 更多