Reputation: 50
I am creating a Python Tkinter MVC project using dataclasses and I would like to create widgets by iterating through the dictionary generated by the asdict method (when passed to the view, via the controller); however, there are attributes which I don't wish to include in the set of widgets. Before this edit I posted something similar to the class below (this is now more specific to the project I am working on, thanks to @Prune, @Cameron_McFee and @Brian_McCutchon for their responses). Is there a way to exclude attributes from the asdict method? In the example below I don't want to include the 'customer' in the dictionary.
I tried, experimentally, including the two field specifications - repr=False and init=False on two of the fields but I guessed they wouldn't work and they don't.
@dataclass
class Product:
name: str
description: str = field(repr=False)
N: float = field(init=False, default=0.0)
P: float
K: float
_customer = None #class variable until assigned
self._customer # but 'self' doesn't exist in this context.
@property
def customer(self):
return self._customer
@customer.setter
def customer(self, value):
self._customer = value
I understand there are different ways to construct the class to achieve this, perhaps avoiding dataclasses, e.g:
class Product:
def __init__(self, name: str, description: str, N: float, P: float, K: float):
self.name = name
self.description = description
self.N = N
self.P = P
self.K = K
self._customer = None
@property
def customer(self):
return self._customer
@customer.setter
def customer(self, value):
self._customer = value
This involves more boilerplate which I would like to avoid if possible. An imperfect analogy would be a model in C# which can be instantiated using Dapper or EF.
Upvotes: 2
Views: 3198
Reputation: 21
You can use InitVar
:
from dataclasses import asdict, dataclass, InitVar, field
@dataclass
class A:
a: int
b: str
ignore_me: InitVar[bool] = field()
a = A(1, "2", False)
print(asdict(a)) # prints "{'a': 1, 'b': '2'}"
Details:
asdict
internally uses fileds()
for dataclass instances, but from docs we know that:
InitVar
is not returned by the module-levelfields()
function
Upvotes: 0
Reputation: 396
From PEP 557:
The dataclass decorator examines the class to find fields. A field is defined as any variable identified in annotations. That is, a variable that has a type annotation. With two exceptions described below, none of the Data Class machinery examines the type specified in the annotation.
So it's valid python code but the _dib
class variable (or the dib property) will not be included in the generated comparative methods as _dib
is not in __annotations__
Upvotes: 1