diff --git a/README.md b/README.md index 18a8674..a6d1a37 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ working across different projects via [VisualMode](https://www.visualmode.dev/). For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter). -_1845 TILs and counting..._ +_1846 TILs and counting..._ See some of the other learning resources I work on: @@ -1073,6 +1073,7 @@ If you've learned something here, support my efforts writing daily TILs by - [Access Most Recent Return Value In REPL](python/access-most-recent-return-value-in-repl.md) - [Access SQLite Result Values By Name With Row Factory](python/access-sqlite-result-values-by-name-with-row-factory.md) - [Access Variables Outside Loop Scope](python/access-variables-outside-loop-scope.md) +- [Another Way To Mark Keyword-Only Dataclass Fields](python/another-way-to-mark-keyword-only-dataclass-fields.md) - [Argument Defaults Are Evaluated When Function Is Defined](python/argument-defaults-are-evaluated-when-function-is-defined.md) - [Assert Is Only A Development Check](python/assert-is-only-a-development-check.md) - [Avoid Modification With Frozen Dataclass](python/avoid-modification-with-frozen-dataclass.md) diff --git a/python/another-way-to-mark-keyword-only-dataclass-fields.md b/python/another-way-to-mark-keyword-only-dataclass-fields.md new file mode 100644 index 0000000..a290c19 --- /dev/null +++ b/python/another-way-to-mark-keyword-only-dataclass-fields.md @@ -0,0 +1,47 @@ +# Another Way To Mark Keyword-Only Dataclass Fields + +In [Configure Other Attributes Of Dataclass +Field](configure-other-attributes-of-dataclass-field), I showed how the +[`dataclasses.field`](https://docs.python.org/3/library/dataclasses.html#dataclasses.field) +constructor function can be used. One of the parameters I demonstrated was +`kw_only`. Each field constructed with `kw_only=True` will be required to be +passed as a keyword-only parameter when constructing an instance of that +`dataclass`. + +Another way to specify keyword-only parameters with `dataclass` fields is to +segment them with `KW_ONLY`. This sentinel value can be included as a +pseudo-field where all fields that come after it are treated as keyword-only. + +Translating the example from that other post would look like this: + +```python +from dataclasses import dataclass, field, KW_ONLY +from datetime import datetime + +@dataclass +class Session: + start_time: datetime + project_name: str + _: KW_ONLY + tags: list[str] = field(default_factory=list, kw_only=True) + end_time: datetime | None = None + + # ... + +sesh1 = Session(start1, "my-project", tags=["pytorch", "numpy"]) +sesh2 = Session(start2, "other-project", end_time=datetime.now()) +``` + +The field whose value is `KW_ONLY` is only used to signal that keyword-only +boundary. It does not itself become a field of the dataclass. + +On the one hand I like this approach because it feels closer to [the way this is +signaled in standard function definition +syntax](force-remaining-arguments-to-be-named.md). + +```python +def build_session(start_time, project_name, *, tags, end_time=None) +``` + +On the other hand, it feels like magic `dataclass` syntax whereas the +`kw_only=True` parameter is more explicit.