OOP
#!/usr/bin/env python3
class Foo:
= 55 # class attribute
a
# initializer method (callable class attribute)
def __init__(self, x):
self.x = x
# another method (callable class attribute)
def f(self):
print(Foo.a, self.x)
class Bar(Foo):
= 77
b
def __init__(self, x, y):
super().__init__(x)
self.y = y
def g(self):
print(Foo.a, Bar.b, self.x, self.y)
def main():
= Foo(3)
foo print(Foo.a) # 55
print(foo.x) # 3
# 55 3
foo.f()
print('---')
= Bar(4, 5)
bar print(Bar.a) # 55
print(Bar.b) # 77
print(bar.x) # 4
print(bar.y) # 5
# 55 77 4 5
bar.g()
if __name__ == '__main__':
main()
Notes:
Classes have attributes. Some attributes may be callable; those callable class attributes are called “methods”. (We don’t call these instance methods or class methods — they’re just methods. Classes do also have “class methods” (and even static methods), but that’s a different matter.)
Class attributes (including methods) are stored in
C.__dict__
.Methods are defined with
self
as their first parameter.Instance attributes (like those set inside
__init__()
) are stored ininst.__dict__
.When you call a method on an instance, the instance is automatically and implicitly passed as the first argument to the method (that is,
inst.f(arg)
is likeC.f(inst, arg)
). You could instead directly call the method on the class, but that would be out of the ordinary and you’d need to manually pass in the instance as the first arg.Inheritance terminology:
- BaseClass/DerivedClass
- SuperClass/SubClass
- ParentClass/ChildClass
You set instance attributes in
__init__()
.__init__
methods are not “constructors”; they’re initializers. The object has already been constructed by Python before__init__
gets to it.If you don’t write an
__init__()
method, then Python just goes and uses the one in the base class. If you do create one, Python only calls that one (since it overrides the parent’s initializer). If you want parent initializers called (and you do), you need to do that yourself (super().__init__(arg1, arg2, ..)
— no need to passself
).Instance variables are not “inherited”, per se; you either create them (usually via
__init__
’s) or you don’t. If you want to make sure you “inherit” all instance variables, just make sure you call your parent’s__init__
(and it should call it’s parent’s__init__
, and so on), and those__init__
’s are what create the instance variables.