Reputation: 4650
I have a design issue in Python, but I'm not very advanced neither in the language, nor in design, nor in Exceptions.
Here is what I want: I have a class with attributes like name, budget, ... and I want to be impossible to create object with lets say name shorter than 3 symbols and budget < 0. Also I want when changing some of this values, they to be checked again. If you try to create an object which doesn't meet this conditions, I want exception to be thrown.
Here is what I tried:
def __init__(self, name, budget):
try:
self.set_name(name)
self.set_budget(budget)
except Exception as e:
print(e)
return None
def set_name(name):
if len(name) < 3:
raise Exception("short name")
else:
self.__name = name
But here I have two problems :( The first one is that even when I try to create object with the name 'a' for example it IS created :( and I don't want invalid objects to be created. The second problem is that I have print in my init method and I don't want to have any I/O functions in it. But then how to get the message? How to get from the constructor what is the reason for not creating the object?
Also, this is for a very simple task and I don't want to overdo it with sophisticated and too long and hard solution :(
Can you please help me? Thank you very much in advance! :)
Upvotes: 3
Views: 1913
Reputation: 54223
this is for a very simple task and I don't want to overdo it with sophisticated and too long and hard solution
This is the cause of so much gloom and doom in the IT world right now ahem Heartbleed but okay, we'll keep it simple :)
You want to confirm that len(name) >= 3
and budget >= 0
, is that right? Let's do it then:
class Dummy(object):
def __init__(self, name, budget):
self.name = name
self.budget = budget
@property
def name(self):
return self.__name
@name.setter
def name(self,value):
self.validatename(value)
self.__name = value
@property
def budget(self):
return self.__budget
@budget.setter
def budget(self,value):
self.validatebudget(value)
self.__budget = value
def validatename(self,value):
if len(value) < 3:
raise Exception("Some descriptive error here")
def validatebudget(self,value):
if isinstance(value,str):
value = float(value) # this is more common than you'd think
if value < 0:
raise Exception("Some descriptive error here")
This is creating a function to validate each name
and budget
, which throw exceptions (intentionally uncaught in the class, though you could certainly prompt for that if you want!) if the value is wrong. This is not the best way to do it, but as per your quote at the top of my answer, it's the simplest way. It also utilizes python properties (SO question related here) to define a custom functions to handle getting and setting name
and budget
. Let's run an example:
>>> testobj = Dummy("Adam",100000)
# no error
>>> testobj.name
"Adam"
>>> testobj.budget
100000
>>> testobj.name = "Brian"
>>> testobj.name
"Brian"
>>> testobj.name = "Ed"
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
testobj.name = "Ed"
File "<pyshell#34>", line 12, in name
self.validatename(value)
File "<pyshell#34>", line 24, in validatename
raise Exception("Some descriptive error here")
Exception: Some descriptive error here
Upvotes: 3