Aren’t class attributes inherited?
Question:
I have the following python classes:
parent.py
#! /usr/bin/env python3
class parent():
CONSTANT = 10
child.py
#! /usr/bin/env python3
from parent import parent
class child(parent):
print(CONSTANT)
def my_method(self):
print(CONSTANT)
But child
cannot access CONSTANT
.
Why doesn’t that work? Is there a way to access the parent’s class attributes (without transforming them all into instance attributes…)
Answers:
They are inherited.
class parent:
CONSTANT = 10
class child(parent):
pass
print(child.CONSTANT) # 10
You should encase your print
into classmethod
and reference attribute of class rather than global variable, consider following simple example
class Parent:
CONSTANT = 10
class Child(Parent):
@classmethod
def print_constant(cls):
print(cls.CONSTANT)
Child.print_constant()
gives output
10
It already inherited that. Test it without that print line(I’ve put both in a module, but that doesn’t matter the error is from something else, I’m gonna talk about it next):
class parent:
CONSTANT = 10
class child(parent):
pass
print(child.CONSTANT) # 10
But why it throws NameError: name 'CONSTANT' is not defined
in your example?
class
keyword in Python is used to create classes which are instances of type type
. In it’s simplified version, it does the following:
-
Python creates a namespace(an empty dictionary basically) and executes the body of the class in that namespace so that it will be populated with all methods and attributes and so on…
-
Then calls the three-arguments form of type()
. The result of this call is your class which is then assign to a symbol which is the name of your class.
The point is when the body of the class is being executed, it doesn’t know anything about the parent namespace , likewise it doesn’t know what is CONSTANT
. So print(CONSTANT)
is gonna throw a NameError exception.
regarding your comment: Since you already inherited that value, you can access it through both the instance and the class. both work:
class parent:
CONSTANT = 10
class child(parent):
def regular_method(self):
print(self.CONSTANT)
print(self.__class__.CONSTANT)
print(super().CONSTANT)
@classmethod
def class_method(cls):
print(cls.CONSTANT)
obj = child()
obj.regular_method()
obj.class_method()
I have the following python classes:
parent.py
#! /usr/bin/env python3
class parent():
CONSTANT = 10
child.py
#! /usr/bin/env python3
from parent import parent
class child(parent):
print(CONSTANT)
def my_method(self):
print(CONSTANT)
But child
cannot access CONSTANT
.
Why doesn’t that work? Is there a way to access the parent’s class attributes (without transforming them all into instance attributes…)
They are inherited.
class parent:
CONSTANT = 10
class child(parent):
pass
print(child.CONSTANT) # 10
You should encase your print
into classmethod
and reference attribute of class rather than global variable, consider following simple example
class Parent:
CONSTANT = 10
class Child(Parent):
@classmethod
def print_constant(cls):
print(cls.CONSTANT)
Child.print_constant()
gives output
10
It already inherited that. Test it without that print line(I’ve put both in a module, but that doesn’t matter the error is from something else, I’m gonna talk about it next):
class parent:
CONSTANT = 10
class child(parent):
pass
print(child.CONSTANT) # 10
But why it throws NameError: name 'CONSTANT' is not defined
in your example?
class
keyword in Python is used to create classes which are instances of type type
. In it’s simplified version, it does the following:
-
Python creates a namespace(an empty dictionary basically) and executes the body of the class in that namespace so that it will be populated with all methods and attributes and so on…
-
Then calls the three-arguments form of
type()
. The result of this call is your class which is then assign to a symbol which is the name of your class.
The point is when the body of the class is being executed, it doesn’t know anything about the parent namespace , likewise it doesn’t know what is CONSTANT
. So print(CONSTANT)
is gonna throw a NameError exception.
regarding your comment: Since you already inherited that value, you can access it through both the instance and the class. both work:
class parent:
CONSTANT = 10
class child(parent):
def regular_method(self):
print(self.CONSTANT)
print(self.__class__.CONSTANT)
print(super().CONSTANT)
@classmethod
def class_method(cls):
print(cls.CONSTANT)
obj = child()
obj.regular_method()
obj.class_method()