1

I have a NamedTuple one of whose attrs is a changing variable that depends on the context where the instance is initted. For a minimal example, it should be something like

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())

The above code would work fine, but I don't want to expose the timestamp attr to the user. Instead, what I want is something like this, setting timestamp as a default arg which however doesn't lose its independence on the context of initiation:

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)

I expect record.timestamp to be the time of initiation but apparently it is the time of class declaration, i.e., "fixed" from the outset which isn't desirable.

What would be the best practice to do this?

From a pragmatic perspective, true, it doesn't seem to hurt to leave the timestamp arg for external assignment, but I just want to avoid it because of code cleanness.

1 Answer 1

1

I don't think that you can achieve that with named tuples.

If you want a data object that is immutable "of sorts", you could use a frozen dataclass:

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)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.