I have to following exercise:
Implement a class PersonReader supporting the following methods:
input() asks the user for the name and year of birth of a person at shell prompt (using the builtin input function).
str that returns the string "name (year)" (e.g. to be used by the print method when applied to a PersonReader).
And my idea was to do something like this:
class Personreader:
def __init__(self, name, year):
self.name = name
self.year = year
def from_input(x):
return x(input(),input())
def __str__(self):
print(self.name, self.year)
However this gives an error when I try and call Personreader.from_input(x) or Personreader.from_input(). How can implement this user input in my class?
You've defined from_input
as a regular method, this means its first parameter is always self
(no matter what name you give it) and it has to be either called on an instance or provided with an instance.
To make from_input
an alternative constructor (which seems to be the intent here) you should make it into a class method by decorating it with @classmethod
. In that case, the name of the (first) parameter should be cls
e.g.
@classmethod
def from_input(cls):
return cls(input(), input())
Incidentally, your implementation of __str__
is misguided. __str__
should return a visualisation of the object as a string, it should not print it. If you want a printer of some sort, then add a method with that naming e.g. print_object
. Alternatively, fix your __str__
then just print(reader)
or whatever.
Finally, classes are usually CamelCased in python, so it shoud be PersonReader
not Personreader
. Though it's unclear what the reader part is for, your class is just a person, which can incidentally be defined from inputs (colloquially readers are objects which can load data from file or file-like objects e.g. csv.reader
, so a PersonReader
would be something which parses a file or file-like object and loads one or more Person
objects).