Having a simple Python class like this:
class Spam(object): __init__(self, description, value): self.description = description self.value = value
I would like to check the following constraints:
Should I:
1. validate data before creating spam object ?
2. check data on __init__
method ?
3. create an is_valid
method on Spam class and call it with spam.isValid() ?
4. create an is_valid
static method on Spam class and call it with Spam.isValid(description, value) ?
5. check data on setters declaration ?
6. etc.
Could you recommend a well designed/Pythonic/not verbose (on class with many attributes)/elegant approach?
Accessing the attributes of a classgetattr() − A python method used to access the attribute of a class. hasattr() − A python method used to verify the presence of an attribute in a class. setattr() − A python method used to set an additional attribute in a class.
Attributes of a class can also be accessed using the following built-in methods and functions : getattr() – This function is used to access the attribute of object. hasattr() – This function is used to check if an attribute exist or not. setattr() – This function is used to set an attribute.
The validation can be done in two different ways, that is by using a flag variable or by using try or except which the flag variable will be set to false initially and if we can find out that the input data is what we are expecting the flag status can be set to true and find out what can be done next based on the ...
You can use Python properties to cleanly apply rules to each field separately, and enforce them even when client code tries to change the field:
class Spam(object): def __init__(self, description, value): self.description = description self.value = value @property def description(self): return self._description @description.setter def description(self, d): if not d: raise Exception("description cannot be empty") self._description = d @property def value(self): return self._value @value.setter def value(self, v): if not (v > 0): raise Exception("value must be greater than zero") self._value = v
An exception will be thrown on any attempt to violate the rules, even in the __init__
function, in which case object construction will fail.
UPDATE: Sometime between 2010 and now, I learned about operator.attrgetter
:
import operator class Spam(object): def __init__(self, description, value): self.description = description self.value = value description = property(operator.attrgetter('_description')) @description.setter def description(self, d): if not d: raise Exception("description cannot be empty") self._description = d value = property(operator.attrgetter('_value')) @value.setter def value(self, v): if not (v > 0): raise Exception("value must be greater than zero") self._value = v
If you only want to validate the values when the object is created AND passing in invalid values is considered a programming error then I would use assertions:
class Spam(object): def __init__(self, description, value): assert description != "" assert value > 0 self.description = description self.value = value
This is about as concise as you are going to get, and clearly documents that these are preconditions for creating the object.
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