简体   繁体   中英

Create timestamp inside of dataclass when class is instantiated

I am using dataclass and I would like to create a time stamp every time an instance of the class is created, like so:

@dataclass
class test:
    timestamp: datetime = datetime.utcnow()

test1 = test()

However, doing this, yields a timestamp as of the time when I ran the code for original class object. That is, new instances all have the same timestamp.

The approach below does what I want, but I don't understand why. I would think that the above approach should work as well, since there is no instance of that class created. Why do I have to write it with that field approach?

@dataclass
class test:
timestamp: datetime = field(default_factory=datetime.utcnow)

test1 = test()
test1.timestamp

In the first case, the datetime.utcnow() is evaluated when the class is being defined. This effectively gives that fields a default value. When you create an object of the class, that evaluation is not done again - so you're left with a single value shared with all the instances that you create of the class.

On the other hand, default_factory uses a callable that is invoked whenever a new instance of the class is being created - and the result of that invocation is used to populate the field. So when you create an object of the test class, the datetime.utcnow() runs again & a updated timestamp is present in that instance.

Read the docs for more info.

The documentation of dataclasses.field explains it:

…some dataclass features that require additional per-field information. To satisfy this need for additional information, you can replace the default field value with a call to the provided field() function.
. . .
If the default value of a field is specified by a call to field() , then the class attribute for this field will be replaced by the specified default value. If no default is provided, then the class attribute will be deleted. The intent is that after the dataclass() decorator runs, the class attributes will all contain the default values for the fields, just as if the default value itself were specified.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM