Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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

963 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
  • Login to see the comments

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

×