-2

I am new to python and its OOP concepts, I was following below code and got little confused,

class Person:
  species = 'Homo sapiens'
  def __init__(self, name, age):
    self.name= name
    self.age = age

p = Person("ABC", 18)

p.species = 'No homo sapien'
print(p.species)
# prints --> No homo sapien

I haven't accessed or manipulated the value of class attribute species by just doing p.species so it should have thrown some error about species attribute, but got no error instead it did print.

p.__class__.species = 'Not found'
print("ABC is a {}".format(p.__class__.species))
# error --> SyntaxError: expression cannot contain assignment, perhaps you meant "=="?

This statement threw error as expected. So I want clarification regarding first statement. And can we change class attribute value?

Newbie
  • 53
  • 6
  • "so it should have thrown some error about `species` attribute" Why? It would never ordinarily do that. For example, when you do `self.name = name` in the `__init__`, it doesn't raise an exception, even though `self.name` doesn't exist yet. "This statement threw error as expected." No; that error has nothing to do with the code you've shown, and can only happen because of a problem on the previous line of code. There is no problem with the assignment you show there, *whether or not* you have an assignment in the `class` body. – Karl Knechtel Jun 21 '21 at 20:07
  • 1
    Does https://stackoverflow.com/questions/11007627/python-variable-declaration/11008311#11008311 help? – Karl Knechtel Jun 21 '21 at 20:08

1 Answers1

1

When you assign to p.species, you are creating a new instance attribute that shadows the class attribute. Person.species will still evaluate to "Homo Sapiens".

>>> p = Person("ABC", 18)
>>> p.species = "No homo sapiens"
>>> p.species
'No homo sapiens'
>>> Person.species
'Homo sapiens'

If you want to change a class attribute, you have to do it via the class.

>>> p = Person("ABC", 18)
>>> Person.species = "Canis canis"
>>> p.species
'Canis canis'

Because no instance attribute named species exists, p.species falls back to Person.species.

chepner
  • 497,756
  • 71
  • 530
  • 681