0

I tried adding property decorators to my class but something went wrong.

I got 6 errors!!!

my code:

class person:

    def __init__ (self, name, age):
        self.name = name
        self.age = age
    @property
    def age(self):
        return self.age
    @age.setter
    def age(self, new_age):
        if isinstance(new_age, int):
            self.age = new_age
    def __str__ (self):
        return f"{self.name} is {self.age}"
p1 = person('moe',34)

print(person)
wjandrea
  • 28,235
  • 9
  • 60
  • 81
blobodep
  • 119
  • 1
  • 7
  • 1
    Can you be more specific as to _what_ the errors are? Can you edit your question to include their stacktraces? – Green Cloak Guy Jun 09 '20 at 15:26
  • 1
    You are printing `person` (class) on the last line, not `p1` (class instance) – Pavel Botsman Jun 09 '20 at 15:26
  • 1
    Try using unique names - currently your property def age() and self.age are the same name. change one to something different - Study the documentation: https://docs.python.org/3/library/functions.html#property – Patrick Artner Jun 09 '20 at 15:29
  • yes thanks everyone for explaining. I forgot to add p1 in the print function instead of person lol aside from the same name mistake – blobodep Jun 09 '20 at 16:11

3 Answers3

1

You are using same names and the property then shadows the member. This makes these recursion issue as self.age calls itself again and again in setter. You need to use different attribute name, like this:

class person:

    def __init__ (self, name, age):
        self.name = name
        self._age = age
    @property
    def age(self):
        return self._age
    @age.setter
    def age(self, new_age):
        if isinstance(new_age, int):
            self._age = new_age

    def __str__ (self):
        return f"{self.name} is {self.age}"

p1 = person('moe',34)
print(p1)
Zain Arshad
  • 1,885
  • 1
  • 11
  • 26
  • yes i did get a recursion error. I didn't quite understand your explanation. How is it coming from the setter??? why did you change the attribute's name – blobodep Jun 09 '20 at 16:03
  • See in your `setter` you have `self.age = new_age`, this line will again call the `setter` and this will go again and again until max recursion is reached. You have to use someother name. One more thing you can't have same name of r methods and members of a class. Ask if you still have any confusion – Zain Arshad Jun 09 '20 at 16:06
  • Thank you I understood what you meant but what does "the property shadows the member" mean – blobodep Jun 09 '20 at 16:07
  • It means that if property name is `age` and member name is `age` then whenever you use `classname.age` it will mean you are accessing the property. For example there is method `input()` if you have a variable named `input` it will shadow the built-in `input()` and you won't be able to use it, give it a try you will understand – Zain Arshad Jun 09 '20 at 16:09
  • @blobodep New users must take this to account, that if they find the answer correct and it resolves their issue, then kindly mark that as answer. so that if someone have the same issue in future they can get a handy help without asking a new question. That's how things work here . Welcome to SO :) – Zain Arshad Jun 09 '20 at 16:13
  • how do i mark it as answered and what is "member name" – blobodep Jun 09 '20 at 16:17
  • [How to mark as answer](https://stackoverflow.com/help/someone-answers#:~:text=To%20accept%20an%20answer%3A&text=To%20mark%20an%20answer%20as,the%20answer%2C%20at%20any%20time.) member means an attribute of the class. – Zain Arshad Jun 09 '20 at 16:20
  • 1
    Thanks for your time i marked my question as answered :) – blobodep Jun 09 '20 at 16:23
1

You defined age both as a class method and a class variable. When you refer to self.age, the interpreter has no way of knowing what you meant.

Change the code to this to fix it:

class person:

    def __init__ (self, name, age):
        self.name = name
        self._age = age
    @property
    def age(self):
        return self._age
    @age.setter
    def age(self, new_age):
        if isinstance(new_age, int):
            self._age = new_age
    def __str__ (self):
        # Here you can either use the property or the real variable
        return f"{self.name} is {self.age}" 
p1 = person('moe',34)

print(person)
arscisca
  • 76
  • 3
0

There may be two mistakes in your code.

  1. First, methods and attributes shouldn't have the same name age.
  2. You should print the instance p1, if I understand your intention correctly.

Something like this:

class person:

    def __init__ (self, name, age):
        self.name = name
        self._age = age
    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, new_age):
        if isinstance(new_age, int):
            self._age = new_age
    def __str__ (self):
        return f"{self.name} is {self._age}"
p1 = person('moe',34)

print(p1)

You get:

moe is 34
expectedAn
  • 96
  • 9