Currently I have something like
if name and password:
user = User(name, password)
...do stuff
I'd like to refactor it to something:
user = User(name, password)
if user:
...do stuff
I create a User()
class:
class User():
def __init__(self, name, password):
if name and password:
self.name, self.password = name, password
but in this case even if name
or password
are None
, user
still gets instantiated (empty but still exists, so the if user:
test is true).
How to would I not instantiate an object based on specific arguments?
__init__ is required to return None. You cannot (or at least shouldn't) return something else. Try making whatever you want to return an instance variable (or function).
In Python, the constructor does not return any value. Therefore, while declaring a constructor, we don't have anything like return type. Instead, a constructor is implicitly called at the time of object instantiation. Thus, it has the sole purpose of initializing the instance variables.
__new__ method will be called when an object is created and __init__ method will be called to initialize the object. In the base class object , the __new__ method is defined as a static method which requires to pass a parameter cls .
You'll have to use a __new__
method; by the time __init__
is called a new instance has already been created.
class User(object):
def __new__(cls, name, password):
if name and password:
instance = super(User, cls).__new__(cls)
instance.name, instance.password = name, password
return instance
However, you are violating expectations; when you call a class, I'd expect to always get a new instance. Either raise an exception, or use a classmethod instead.
Raising an exception:
class User(object):
def __init__(self, name, password):
if not (name and password):
raise ValueError('Empty name or password not allowed')
self.name, self.password = name, password
try:
user = User(name, password)
except ValueError:
# oops, no username or password
else:
# ...do stuff
or using a classmethod:
class User(object):
def __init__(self, name, password):
self.name, self.password = name, password
@classmethod
def create_valid_user(cls, name, password):
"""Create a user, or return None if conditions are not met"""
if not (name and password):
return None
return cls(name, password)
user = User.create_valid_user(name, password)
if user is not None:
# ...do stuff
It's wrong way. You shold add a method in your User class named check(). Or(better way), create a static method createUser(name, password). It looks like:
user = User.createUser(name, password)
Something like this :
class User():
def __init__(self, name, password):
self._name = self._password = None
self.name = name
self.password = password
@property
def name(self):
return self._name
@name.setter
def name(self, name: str) -> None:
if not name:
raise TypeError("name is required")
if len(name) < 5: # exemple
raise ValueError("name must have 5 characters or more")
self._name = name
# Do the same for password
Then do something like this in your code, or put it in a class method as Factory pattern and return it.
try:
user = User(name, password)
except (TypeError, ValueError):
user = None
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