Why You Should Use     super() Though It Sucks       Eunchong YU    kroisse@gmail.com
유은총● Developing with Python for Food● StyleShare     (2011-2012)● SmartStudy (2012-)● http://blog.materialistic.kr/● https...
Extend
class A:    def parts(self):        return [plate, nail]class B(A):    def parts(self):        # old-way (before Python 2....
class A(object): # new-style class    def parts(self):        return [plate, nail]class B(A):    def parts(self):        b...
super(Class, self)
Old-fashioned wayclass B(A):    def parts(self, lamp):        base = A.parts(self, lamp)        return base + [lamp]class ...
Using super() with new-style classesclass B(A):    def parts(self, lamp):        base = super(B, self).parts(lamp)        ...
Diamond Problem                  class D(B, C)    class B(A)                     class C(A)                 class A(object)
class A(object):      class B(A):    def say(self):        def say(self):        print A,            print B,             ...
MRO● Method Resolution Order● linearize class hierarchy   ○ using C3 algorithm● only for new-style classes
class D(B, C)   class B(A)                     class C(A)                        class A                       (object)D._...
B                   I                       A                D object                       C         G         H         ...
class A(object):           class B(A):  def say(self):             def say(self):    print A,                 print B,    ...
super(Class, self)to find current position   to traverse            of the MRO     entire MRO
super(Class, self)● only for new-style classes● because classic classes dont have MRO
Why You Should Use     super() Though It Sucks
Diamond, Again                 class D(B, C)    class B(A)                   class C(A)                    class A        ...
class A(object):              class C(A):  def say(self):                def say(self, arg):    print A,                  ...
super(Class, self)● Does not call the superclass● Call the next method in the MRO● You cant expect what will be next
Remember #1:● Dont change the method signature  OR● Send all received arguments to super()
class A(object):              class C(A):  def say(self, arg):           def say(self, arg):    print A,                  ...
class A(object):  def say(self, *args, **kwargs):    print A,class B(A):  def say(self, *args, **kwargs):    print B,    s...
Initialize
class A(object):    def __init__(self):        print A: initclass B(object):    def __init__(self):        print B: initcl...
C.__mro__ == (C, A, B, object)                   class C(A, B) class A(object)                   class B(object)          ...
C.__mro__ == (C, A, B, object)                   class C(A, B) class A(object)                   class B(object)          ...
class A(object):    def __init__(self):        print A: init        super(A, self).__init__()class B(object):    def __ini...
class A(object):    def __init__(self, *args, **kwargs):        print A: init        super(A, self).__init__(*args, **kwar...
Remember #2:● Dont forget super(C, self).__init__()●   but how about arguments?
super(Me, self).__init__()           vs.  Parent.__init__(self)
class A(object):       class C(A):  def say(self):         def say(self):    print A,             print C,                ...
Remember #3:● Dont mix both style● Caution: classic classes (before Python 2.1)  ○ obsoleted in Python 3.x  ○ remained in ...
Plenty of pitfalls in super()● verbose syntax — fragile on copy & paste :)● cant use: super(C, self)[0]● super(C) ≠ super(...
...but we should use super()● Its a standard.● Safer to multiple inheritance● If you mix with classic style,  everything w...
References:●   https://fuhm.net/super-harmful/●   https://groups.google.com/forum/?hl=en&fromgroups=#!topic/comp.lang.    ...
Upcoming SlideShare
Loading in …5
×

Why you should use super() though it sucks

654 views

Published on

Python Korea FB Group Seminar 2013 Jan. http://onoffmix.com/event/11742

Speaker Deck: https://speakerdeck.com/kroisse/why-you-should-use-super-though-it-sucks
Google docs: https://docs.google.com/presentation/d/1NaDrIReaKD8qJhkTfyDEnt_FMReVR6aHbZ7RJVBhKf8/pub

Published in: Technology
  • Be the first to comment

Why you should use super() though it sucks

  1. 1. Why You Should Use super() Though It Sucks Eunchong YU kroisse@gmail.com
  2. 2. 유은총● Developing with Python for Food● StyleShare (2011-2012)● SmartStudy (2012-)● http://blog.materialistic.kr/● https://github.com/kroisse
  3. 3. Extend
  4. 4. class A: def parts(self): return [plate, nail]class B(A): def parts(self): # old-way (before Python 2.2) base = A.parts(self) return base + [screw]>>> b = B()>>> b.parts()[plate, nail, screw]
  5. 5. class A(object): # new-style class def parts(self): return [plate, nail]class B(A): def parts(self): base = super(B, self).parts() return base + [screw]>>> b = B()>>> b.parts()[plate, nail, screw]
  6. 6. super(Class, self)
  7. 7. Old-fashioned wayclass B(A): def parts(self, lamp): base = A.parts(self, lamp) return base + [lamp]class C(B): def parts(self, lamp): base = B.parts(self, lamp) return sorted(base)
  8. 8. Using super() with new-style classesclass B(A): def parts(self, lamp): base = super(B, self).parts(lamp) return base + [lamp]class C(B): def parts(self, lamp): base = super(C, self).parts(lamp) return sorted(base)
  9. 9. Diamond Problem class D(B, C) class B(A) class C(A) class A(object)
  10. 10. class A(object): class B(A): def say(self): def say(self): print A, print B, A.say(self)class C(A): class D(B, C): def say(self): def say(self): print C, print D, A.say(self) B.say(self) C.say(self) >>> D().say() D B A C A
  11. 11. MRO● Method Resolution Order● linearize class hierarchy ○ using C3 algorithm● only for new-style classes
  12. 12. class D(B, C) class B(A) class C(A) class A (object)D.__mro__ == (D, B, C, A, object)C.__mro__ == (C, A, object)B.__mro__ == (B, A, object)A.__mro__ == (A, object)
  13. 13. B I A D object C G H E FI.__mro__ == (I, H, D, B, F, G, C, A, E, object)H.__mro__ == (H, D, B, F, G, C, A, E, object)D.__mro__ == (D, B, C, A, object)B.__mro__ == (B, A, object)F.__mro__ == (F, C, A, E, object)G.__mro__ == (G, C, A, object)C.__mro__ == (C, A, object)A.__mro__ == (A, object)E.__mro__ == (E, object)
  14. 14. class A(object): class B(A): def say(self): def say(self): print A, print B, super(B, self).say()class C(A): class D(B, C): def say(self): def say(self): print C, print D, super(C, self).say() super(D, self).say() D.__mro__ == (D, B, C, A, object) >>> D().say() D B C A
  15. 15. super(Class, self)to find current position to traverse of the MRO entire MRO
  16. 16. super(Class, self)● only for new-style classes● because classic classes dont have MRO
  17. 17. Why You Should Use super() Though It Sucks
  18. 18. Diamond, Again class D(B, C) class B(A) class C(A) class A (object)
  19. 19. class A(object): class C(A): def say(self): def say(self, arg): print A, print C(%s) % arg, super(C, self).say()class B(A): class D(B, C): def say(self): def say(self, arg): print B, print D(%s) % arg, super(B, self).say() super(D, self).say(arg) D.__mro__ == (D, B, C, A, object) >>> D().say(1) D(1) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "...", line ..., in say TypeError: say() takes exactly 1 argument (2 given)
  20. 20. super(Class, self)● Does not call the superclass● Call the next method in the MRO● You cant expect what will be next
  21. 21. Remember #1:● Dont change the method signature OR● Send all received arguments to super()
  22. 22. class A(object): class C(A): def say(self, arg): def say(self, arg): print A, print C(%s) % arg, super(C, self).say(arg)class B(A): class D(B, C): def say(self, arg): def say(self, arg): print B, print D(%s) % arg, super(B, self).say(arg) super(D, self).say(arg) >>> D().say(1) D(1) B C(1) A
  23. 23. class A(object): def say(self, *args, **kwargs): print A,class B(A): def say(self, *args, **kwargs): print B, super(B, self).say(*args, **kwargs)class C(A): def say(self, arg, *args, **kwargs): print C(%s) % arg, super(C, self).say(arg, *args, **kwargs)class D(B, C): def say(self, arg, *args, **kwargs): print D(%s) % arg, super(D, self).say(arg, *args, **kwargs)
  24. 24. Initialize
  25. 25. class A(object): def __init__(self): print A: initclass B(object): def __init__(self): print B: initclass C(A, B): def __init__(self): super(C, self).__init__()>>> C()A: init<__main__.C object at 0x10157f150>>>> # so where is B???
  26. 26. C.__mro__ == (C, A, B, object) class C(A, B) class A(object) class B(object) object
  27. 27. C.__mro__ == (C, A, B, object) class C(A, B) class A(object) class B(object) object
  28. 28. class A(object): def __init__(self): print A: init super(A, self).__init__()class B(object): def __init__(self): print B: init super(B, self).__init__()class C(A, B): def __init__(self): super(C, self).__init__()>>> C()A: initB: init<__main__.C object at 0x10157f150>
  29. 29. class A(object): def __init__(self, *args, **kwargs): print A: init super(A, self).__init__(*args, **kwargs)class B(object): def __init__(self, *args, **kwargs): print B: init super(B, self).__init__(*args, **kwargs)class C(A, B): def __init__(self, *args, **kwargs): super(C, self).__init__(*args, **kwargs)>>> C(hello)A: initB: initTypeError: object.__init__() takes no parameters
  30. 30. Remember #2:● Dont forget super(C, self).__init__()● but how about arguments?
  31. 31. super(Me, self).__init__() vs. Parent.__init__(self)
  32. 32. class A(object): class C(A): def say(self): def say(self): print A, print C, super(C, self).say()class B(A): class D(B, C): def say(self): def say(self): print B, print D, A.say(self) super(D, self).say() D.__mro__ == (D, B, C, A, object) >>> D().say() D B A
  33. 33. Remember #3:● Dont mix both style● Caution: classic classes (before Python 2.1) ○ obsoleted in Python 3.x ○ remained in some standard libs of Python 2.x● Whether using super() or not is a method signature.
  34. 34. Plenty of pitfalls in super()● verbose syntax — fragile on copy & paste :)● cant use: super(C, self)[0]● super(C) ≠ super(C, C)
  35. 35. ...but we should use super()● Its a standard.● Safer to multiple inheritance● If you mix with classic style, everything will be broken.
  36. 36. References:● https://fuhm.net/super-harmful/● https://groups.google.com/forum/?hl=en&fromgroups=#!topic/comp.lang. python/qswq2zIKS7I● http://www.python.org/download/releases/2.2.3/descrintro/#cooperation● http://docs.python.org/2/reference/datamodel.html#newstyle● http://www.python.org/dev/peps/pep-3135/● http://freshfoo.com/blog/object__init__takes_no_parameters

×