I am getting into some serious OOP with Python and am running into some issues. I have a class with an initialiser, three private variables and set and get methods for each variable.
Additionally, it has an input method that lets the user enter a value for the variables when they are called, rather than requiring an input
call in the main function that passes a value to the class set method. This way I can immediately validate the user entry within the method specific to the data requirements:
def input_first_name(self):
done = 0
while done == 0:
print("Input First Name:",end='')
first_name = input()
if first_name.isalpha():
self.__first_name = first_name
done = 1
else:
print("Invalid Entry. Please use alphabetic characters only.")
Using these input methods, I have another method that uses them to create a new class instance (just wait, I already know what you're thinking):
@classmethod
def new(cls):
cls.input_first_name(cls)
cls.input_last_name(cls)
cls.input_birthday(cls)
return cls
So I know that using this, I won't have actually instantiated a new instance. However, using the methods doesn't immediately throw any errors. But when I refer to my newly created instance with the get method, that's where I get into trouble that I know is related to not instantiating.
new_relative = Relative.new()
print(new_relative.get_first_name())
results in:
TypeError: get_first_name() missing 1 required positional argument: 'self'
Is there away to a way to have a class method usable in my main function for instantiating a new instance that employs my idea of user input and validation in a simple and elegant manner?
For reference, a minimal sample of the class:
class Relative:
__first_name = ""
__last_name = ""
__birthday = 0
def __init__(self, first_name,last_name,birthday):
self.__first_name = first_name
self.__last_name = last_name
self.__birthday = birthday
def get_first_name(self):
return self.__first_name
I would do this with properties (the Pythonic replacement for endless
get
s andset
s, see e.g. Python @property versus getters and setters), and leave only theinput
to a class method. Here is a minimal example:In use:
Note that:
Relative._valid_name
makes it easy to validate first and last names with the same rules (you could also add a middle name, and easily make that the same too).@property
means that the user can't set an incorrect name at any point, without forcing them to call a specific method to get/set values.