Alex Rembish
Slightly Retarded Senior Python Zombie Evangelist
Aleksey Rembish
Siberian
Python Enthusiast
Lead Python/DevOps programmer at
Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.
class Language:
def hello(self, name):
return "Hello from {0}".format(name)
class Python27(Language):
def hello(self):
return super(Python27, self) \
.hello("Python 2.7")
print Python27().hello()
class Language:
def hello(self, name):
return "Hello from {0}".format(name)
class Python27(Language):
def hello(self):
return super(Python27, self) \
.hello("Python 2.7")
print Python27().hello()
TypeError: super() argument 1 must be type, not classobj
class Language:
def hello(self, name):
return "Hello from {0}".format(name)
class Python35(Language):
def hello(self):
return super(Python35, self) \
.hello("Python 3.5")
print(Python35().hello())
class Language:
def hello(self, name):
return "Hello from {0}".format(name)
class Python35(Language):
def hello(self):
return super(Python35, self) \
.hello("Python 3.5")
print(Python35().hello())
Hello from Python 3.5
class Colour(object): # Python 2.7
def __init__(self, rgb):
self.rgb = rgb
def describe(self):
return "#{0}".format(self.rgb)
class Blue(Colour):
def __init__(self):
super().__init__("0000FF")
print Blue().describe()
class Colour(object): # Python 2.7
def __init__(self, rgb):
self.rgb = rgb
def describe(self):
return "#{0}".format(self.rgb)
class Blue(Colour):
def __init__(self):
super().__init__("0000FF")
print Blue().describe()
TypeError: super() takes at least 1 argument (0 given)
class Colour(object): # Python 3.5
def __init__(self, rgb):
self.rgb = rgb
def describe(self):
return "#{0}".format(self.rgb)
class Yellow(Colour):
def __init__(self):
super().__init__("FFFF00")
print(Yellow().describe())
class Colour(object): # Python 3.5
def __init__(self, rgb):
self.rgb = rgb
def describe(self):
return "#{0}".format(self.rgb)
class Yellow(Colour):
def __init__(self):
super().__init__("FFFF00")
print(Yellow().describe())
#FFFF00
super().method() == super(SubClass, self).method()
class Czechia(object): # Both Pythons
def whereami(self):
print("I'm in Czechia")
Czechia().whereami()
class Czechia(object): # Both Pythons
def whereami(self):
print("I'm in Czechia")
Czechia().whereami()
I'm in Czechia
class Czechia(object): # Both Pythons
def whereami(self):
print("I'm in Czechia")
class Slovakia(object):
def whereami(self):
print("I'm in Slovakia")
super(Slovakia, self).whereami()
# Dash war begins
class Czechoslovakia(Czechia, Slovakia):
def whereami(self):
super(Czechoslovakia, self).whereami()
print("I'm in Czechoslovak Republic")
Czechoslovakia().whereami()
class Czechia(object): # Both Pythons
def whereami(self):
print("I'm in Czechia")
class Slovakia(object):
def whereami(self):
print("I'm in Slovakia")
super(Slovakia, self).whereami()
# Dash war begins
class Czechoslovakia(Czechia, Slovakia):
def whereami(self):
super(Czechoslovakia, self).whereami()
print("I'm in Czechoslovak Republic")
Czechoslovakia().whereami()
I'm in Czechia I'm in Czechoslovak Republic
class Czechia(object): # Both Pythons
def whereami(self):
print("I'm in Czechia")
class Slovakia(object):
def whereami(self):
print("I'm in Slovakia")
super(Slovakia, self).whereami()
# Dash war continues (I can't use dash in a class name)
class Czecho_SlovakRepublic(Slovakia, Czechia):
def whereami(self):
super(Czecho_SlovakRepublic, self).whereami()
print("I'm in Czecho-Slovak Republic")
Czecho_SlovakRepublic().whereami()
class Czechia(object): # Both Pythons
def whereami(self):
print("I'm in Czechia")
class Slovakia(object):
def whereami(self):
print("I'm in Slovakia")
super(Slovakia, self).whereami()
# Dash war continues (I can't use dash in a class name)
class Czecho_SlovakRepublic(Slovakia, Czechia):
def whereami(self):
super(Czecho_SlovakRepublic, self).whereami()
print("I'm in Czecho-Slovak Republic")
Czecho_SlovakRepublic().whereami()
I'm in Slovakia I'm in Czechia I'm in Czecho-Slovak Republic
Czechoslovakia
<class 'Czechoslovakia'>
<class 'Czechia'>
<class 'Slovakia'>
<class 'object'>
Czecho_SlovakRepublic
<class 'Czecho_SlovakRepublic'>
<class 'Slovakia'>
<class 'Czechia'>
<class 'object'>
super() calls
class Reptile(object): # Both Pythons
def describe(self):
return "Reptile"
class Snake(Reptile):
def describe(self):
return "Snake"
class Python(Snake):
def describe(self):
return "Python"
print(super(Python, Python()).describe())
class Reptile(object): # Both Pythons
def describe(self):
return "Reptile"
class Snake(Reptile):
def describe(self):
return "Snake"
class Python(Snake):
def describe(self):
return "Python"
print(super(Python, Python()).describe())
Snake
class Reptile(object): # Both Pythons
def describe(self):
return "Reptile"
class Snake(Reptile):
def describe(self):
return "Snake"
class Python(Snake):
def describe(self):
return "Python"
print(super(Snake, Snake).describe(Python()))
class Reptile(object): # Both Pythons
def describe(self):
return "Reptile"
class Snake(Reptile):
def describe(self):
return "Snake"
class Python(Snake):
def describe(self):
return "Python"
print(super(Snake, Snake).describe(Python()))
Reptile
class Meetup(object): # Both Pythons
name = "Meetup"
class PythonMeetup(Meetup):
name = "Python Meetup"
class PyVo(PythonMeetup):
name = "PyVo"
type = super(PythonMeetup)
print(Meetup.name)
print(PythonMeetup().name)
print(PyVo().name)
class Meetup(object): # Both Pythons
name = "Meetup"
class PythonMeetup(Meetup):
name = "Python Meetup"
class PyVo(PythonMeetup):
name = "PyVo"
type = super(PythonMeetup)
print(Meetup.name)
print(PythonMeetup().name)
print(PyVo().name)
Meetup Python Meetup PyVo
class Meetup(object): # Both Pythons
name = "Meetup"
class PythonMeetup(Meetup):
name = "Python Meetup"
class PyVo(PythonMeetup):
name = "PyVo"
type = super(PythonMeetup)
print(PyVo().type.name)
class Meetup(object): # Both Pythons
name = "Meetup"
class PythonMeetup(Meetup):
name = "Python Meetup"
class PyVo(PythonMeetup):
name = "PyVo"
type = super(PythonMeetup)
print(PyVo().type.name)
Meetup
something = super(PythonMeetup)
print(type(something)) # => <type 'super'>
# `something` is unbounded super object
print(something.name) # => ?
something = super(PythonMeetup)
print(something.name)
# AttributeError: 'super' object has no
# attribute 'name'
print(dir(something))
# [
# '__get__', '__getattribute__',
# '__init__', '__new__', ...
# ]
sup = PyVo().type
print(type(sup)) # => <type 'super'>
pyvo = PyVo()
pyvo.type.name
# == super(PythonMeetup).__get__(pyvo, PyVo).name
# == super(PythonMeetup, pyvo).name
# == "Meetup"
class Meetup(object): # Both Pythons
name = "Meetup"
class PythonMeetup(Meetup):
name = "Python Meetup"
class PyVo(PythonMeetup):
name = "PyVo"
type = super(PythonMeetup)
print(PyVo.type.name)
class Meetup(object): # Both Pythons
name = "Meetup"
class PythonMeetup(Meetup):
name = "Python Meetup"
class PyVo(PythonMeetup):
name = "PyVo"
type = super(PythonMeetup)
print(PyVo.type.name)
AttributeError: 'super' object has no attribute 'name'
class Human(object): # Both Pythons
@classmethod
def mynameis(cls):
print("Human said: I'm {0}".format(cls.__name__))
Human().mynameis()
class Human(object): # Both Pythons
@classmethod
def mynameis(cls):
print("Human said: I'm {0}".format(cls.__name__))
Human().mynameis()
Human said: I'm Human
class Human(object): # Both Pythons
@classmethod
def mynameis(cls):
print("Human said: I'm {0}".format(cls.__name__))
class Pepa(Human):
@classmethod
def mynameis(cls):
print("Pepa said: I'm {0}".format(cls.__name__))
cls.__super.mynameis()
Pepa._Pepa__super = super(Pepa)
Pepa().mynameis()
Edit from 2022: There is a mistake in this code. It will produce an AttributeError for Pepa and Josef (next slides). Check this snippet to observe working, but wacky behavior of super().
Pepa._Pepa__super?!
class Human(object): # Both Pythons
@classmethod
def mynameis(cls):
print("Human said: I'm {0}".format(cls.__name__))
class Pepa(Human):
@classmethod
def mynameis(cls):
print("Pepa said: I'm {0}".format(cls.__name__))
cls.__super.mynameis()
Pepa._Pepa__super = super(Pepa)
Pepa().mynameis()
Pepa said: I'm Pepa
class Human(object): # Both Pythons
@classmethod
def mynameis(cls):
print("Human said: I'm {0}".format(cls.__name__))
class Pepa(Human):
@classmethod
def mynameis(cls):
print("Pepa said: I'm {0}".format(cls.__name__))
cls.__super.mynameis()
Pepa._Pepa__super = super(Pepa)
Pepa().mynameis()
== super(Pepa, self).mynameis()
class Human(object): # Both Pythons
@classmethod
def mynameis(cls):
print("Human said: I'm {0}".format(cls.__name__))
class Pepa(Human):
@classmethod
def mynameis(cls):
print("Pepa said: I'm {0}".format(cls.__name__))
cls.__super.mynameis()
Pepa._Pepa__super = super(Pepa)
class Josef(Pepa):
pass
Josef._Josef__super = super(Josef)
Josef().mynameis()
class Human(object): # Both Pythons
@classmethod
def mynameis(cls):
print("Human said: I'm {0}".format(cls.__name__))
class Pepa(Human):
@classmethod
def mynameis(cls):
print("Pepa said: I'm {0}".format(cls.__name__))
cls.__super.mynameis()
Pepa._Pepa__super = super(Pepa)
class Josef(Pepa):
pass
Josef._Josef__super = super(Josef)
Josef().mynameis()
AttributeError: 'super' object has no attribute 'mynameis'
By Alex Rembish