If I execute the following:
@dataclass
class Test:
hi: Optional[str] = field(
default_factory=lambda: str(uuid.uuid1()))
@dataclass
class Test2:
hi: Optional[str] = str(uuid.uuid1())
if __name__ == "__main__":
a = Test() # Test(hi='115a865c-33be-11eb-94a1-34c93db23648')
b = Test() # Test(hi='115a865d-33be-11eb-8c6f-34c93db23648')
c = Test2() # Test2(hi='10e44300-33be-11eb-85eb-34c93db23648')
d = Test2() # Test2(hi='10e44300-33be-11eb-85eb-34c93db23648')
Why Test
will return for every instance a different uuid, while Test2
will return the same each time?
Also, why default factory
is needed and not default
?
As stated in the docs
default_factory: If provided, it must be a zero-argument callable that will be called when a default value is needed for this field. Among other purposes, this can be used to specify fields with mutable default values, as discussed below. It is an error to specify both default and default_factory.
In your first example
@dataclass
class Test:
hi: Optional[str] = field(
default_factory=lambda: str(uuid.uuid1()))
you pass an anonymous function to the default factory.
To make things easier, lets make a non anonymous function.
def get_new_uuid() -> str:
return str(uuid.uuid1())
@dataclass
class Test:
hi: Optional[uuid.UUID] = field(default_factory=get_new_uuid)
so each instance of Test
calls get_new_uuid
function to obtain new uuid, when initialized.
Your second example assigns a default value.
@dataclass
class Test2:
hi: Optional[str] = str(uuid.uuid1())
It's an equivalent of this
@dataclass
class Test2:
hi: Optional[str] = field(default=str(uuid.uuid1()))
As you can see, here default
parameter is used, while previously it was default_factory
. Here, you don't pass a function, but a value. It's a one-time thing.
In Test
you can't access hi
without instantiating it.
But Test2
has default value assigned on import, so you can access it without instantiating. It's similar to class attribute and instance attribute defined in __init__
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With