Let’s say I have this class:
class Person: def __init__(self, name): self.name = name
If I want to instantiate Person
I can do:
me = Person("António")
But what if I only want to instantiate Person
if name
has type str
?
I tried this:
class Person: def __init__(self, name): if type(name) == str: self.name = name
But then when I do:
me = Person("António") print(me.name) you = Person(1) print(you.name)
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:
class PersonNameError(Exception): pass class Person: def __init__(self): self.name = None def person_from_name(name: str) -> Person: """Person factory that checks if the parameter name is valid returns a Person object if it is, or raises an error without creating an instance of Person if not. """ if isinstance(name, str): p = Person() p.name = name return p raise PersonNameError('a name must be a string') p = person_from_name('Antonio')
Whereas:
p = person_from_name(123) # <-- parameter name is not a string
throws an exception:
PersonNameError Traceback (most recent call last) <ipython-input-41-a23e22774881> in <module> 14 15 p = person_from_name('Antonio') ---> 16 p = person_from_name(123) <ipython-input-41-a23e22774881> in person_from_name(name) 11 p.name = name 12 return p ---> 13 raise PersonNameError('a name must be a string') 14 15 p = person_from_name('Antonio') PersonNameError: a name must be a string