Let’s say I have this class:
JavaScript
x
4
1
class Person:
2
def __init__(self, name):
3
self.name = name
4
If I want to instantiate Person
I can do:
JavaScript
1
2
1
me = Person("António")
2
But what if I only want to instantiate Person
if name
has type str
?
I tried this:
JavaScript
1
5
1
class Person:
2
def __init__(self, name):
3
if type(name) == str:
4
self.name = name
5
But then when I do:
JavaScript
1
6
1
me = Person("António")
2
print(me.name)
3
4
you = Person(1)
5
print(you.name)
6
I get this:
So all that’s happening is:
- If
name
isstr
, the instance has a.name
method - If
name
is notstr
, the instance has no.name
method
But what I actually want, is to stop instantiation all together if name is not an str
.
In other words, I want it to be impossible to create an object from the Person
class with a non str
name
.
How can I do that?
Advertisement
Answer
You could use a factory that checks the parameters, and returns a Person
object if everything is fine, or raises an error:
maybe something line this:
JavaScript
1
20
20
1
class PersonNameError(Exception):
2
pass
3
4
class Person:
5
def __init__(self):
6
self.name = None
7
8
def person_from_name(name: str) -> Person:
9
"""Person factory that checks if the parameter name is valid
10
returns a Person object if it is, or raises an error without
11
creating an instance of Person if not.
12
"""
13
if isinstance(name, str):
14
p = Person()
15
p.name = name
16
return p
17
raise PersonNameError('a name must be a string')
18
19
p = person_from_name('Antonio')
20
Whereas:
JavaScript
1
2
1
p = person_from_name(123) # <-- parameter name is not a string
2
throws an exception:
JavaScript
1
15
15
1
PersonNameError Traceback (most recent call last)
2
<ipython-input-41-a23e22774881> in <module>
3
14
4
15 p = person_from_name('Antonio')
5
---> 16 p = person_from_name(123)
6
7
<ipython-input-41-a23e22774881> in person_from_name(name)
8
11 p.name = name
9
12 return p
10
---> 13 raise PersonNameError('a name must be a string')
11
14
12
15 p = person_from_name('Antonio')
13
14
PersonNameError: a name must be a string
15