0

I have a question regarding accessing class variable from the class. Which way is preferred? Why Version 1 works? name isn't instance variable, how it can be accessed using .self?

Version 1:

class Base:
    def get_name(self): return self.name

class Child_1(Base):
    name = 'Child 1 name'

child = Child_1()
print(child.get_name())

Version 2:

class Base:
    @classmethod
    def get_name(cls): return cls.name

class Child_1(Base):
    name = 'Child 1 name'

child = Child_1()
print(child.get_name())

Motivation behind this, is defining name once for all instances to save space.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
KocT9H
  • 299
  • 1
  • 4
  • 14
  • Version 1 will not always get the class attribute. If there is an instance attribute `name` it will return that. – Klaus D. May 14 '20 at 07:56
  • 1
    https://stackoverflow.com/a/25577642/6045800 TL;DR - *Well, accessing a class attribute through `self` works just fine. __If there is no instance attribute of the same name__, you get the class attribute. But __assigning to it will hide the class attribute with a new instance attribute of the same name__. Which is probably not what you wanted.* – Tomerikoo May 14 '20 at 07:57
  • Version 1 is typically preferred unless you have a very good reason not to (ie provide more protection against accidentally setting it) – Joran Beasley May 14 '20 at 07:58

1 Answers1

1

self.name by default refers to cls.name

if you set it it only sets it for that instance however

self.name = "bob"

now overrides the class level name

just the same for methods as well

class Foo:
    @staticmethod
    def hello():
        print("Hi There From Foo!")
    def __init__(self):
        self.hello() #this works

 Foo.hello() # this also works
 Foo() # print from in the init
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179