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__
.