Reputation: 179
I'm making a program where I want to verify if the induced value is the right one.
Imagine I want to create an object with a property called name
. That name must be a string, right? Well, I would like to verify this by running this piece of code:
def SetName(self, name):
if not isinstance(name, str):
raise ValueError("It must be a string")
self._name = name
This is my __init__
:
def __init__(self, name:str, price:int, note = None) -> None:
self._name = name
self._price = price
self.note = note
Product.listOfProducts.append(self)
This code works when I input a string, like this:
Margerita = P.Pizza("Margerita", 15, ["Cheese", "Basil"], 10)
However, if I run:
Margerita = P.Pizza(5, 15, ["Cheese", "Basil"], 10)
It raises no error.
What can I do to make the property:
name = property(fget = GetName, fset = SetName)
Work as I described it?
Thank you for your time.
Upvotes: 0
Views: 51
Reputation: 3711
Instead of your approach with a dedicated setter function for each argument, you could use dataclasses in combination with a __post_init__
check for a generalized type check:
from dataclasses import dataclass
list_of_products = []
@dataclass
class Pizza:
name: str
price: int
condiments: list
def __post_init__(self):
for (name, arg_type) in self.__annotations__.items():
if not isinstance(self.__dict__[name], arg_type):
raise TypeError(
f"`{name}` must be `{arg_type.__name__}` "
f"(was `{self.__dict__[name].__class__.__name__}`)"
)
# various other manipulations previously done in your __init__
list_of_products.append(self)
# [...]
margerita = Pizza("foo", 15, ["spam"]) # valid
m4rg3rita = Pizza(42, 15, ["spam"]) # <= raises TypeError: `name` must be `str` (was `int`)
Upvotes: 1