2

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?

1
  • 2
    What is the x parameter? Commented Mar 19, 2020 at 8:19

1 Answer 1

5

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).

Sign up to request clarification or add additional context in comments.

5 Comments

I'm not really sure what a decorator is. Why is necessary that first parameter is cls?
cls refer class attributes, self refer instance attributes.
@Jacobiman Method always takes self (class instance) as first parameter (thing before the dot that calls method), no matter how you name it. Class method always takes cls (class itself) as first parameter (thing before the dot that calls method).
Basically: Personreader.from_input() -> class method from_input gets cls = Personreader. Thus the return value is Personreader(input(), input()) = calls the normal constructor with 2 values entered by the user.
@Jacobiman by default Python methods work on instances. By prefixing the method definition with @classmethod (you can just treat it as magic for now) the method will work on the class itself instead. That also changes the first parameter Python provides from the instance (colloquially named self) to the class object (colloquially named cls). This means you can call Personreader.from_input() and it won't complain that it is missing a parameter (which is what it does by default, because it wants to be called on an instance). This also lets you call the class object to construct.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.