Upcoming SlideShare
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Standard text messaging rates apply

# Why you should use super() though it sucks

308

Published on

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

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

Published in: Technology
1 Like
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
• Be the first to comment

Views
Total Views
308
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
0
0
Likes
1
Embeds 0
No embeds

No notes for slide

### Transcript

• 1. Why You Should Use super() Though It Sucks Eunchong YU kroisse@gmail.com
• 2. 유은총● Developing with Python for Food● StyleShare (2011-2012)● SmartStudy (2012-)● http://blog.materialistic.kr/● https://github.com/kroisse
• 3. Extend
• 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. 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. super(Class, self)
• 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. 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. Diamond Problem class D(B, C) class B(A) class C(A) class A(object)
• 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. MRO● Method Resolution Order● linearize class hierarchy ○ using C3 algorithm● only for new-style classes
• 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. 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. 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. super(Class, self)to find current position to traverse of the MRO entire MRO
• 16. super(Class, self)● only for new-style classes● because classic classes dont have MRO
• 17. Why You Should Use super() Though It Sucks
• 18. Diamond, Again class D(B, C) class B(A) class C(A) class A (object)
• 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. super(Class, self)● Does not call the superclass● Call the next method in the MRO● You cant expect what will be next
• 21. Remember #1:● Dont change the method signature OR● Send all received arguments to super()
• 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. 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. Initialize
• 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. C.__mro__ == (C, A, B, object) class C(A, B) class A(object) class B(object) object
• 27. C.__mro__ == (C, A, B, object) class C(A, B) class A(object) class B(object) object
• 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. 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. Remember #2:● Dont forget super(C, self).__init__()● but how about arguments?
• 31. super(Me, self).__init__() vs. Parent.__init__(self)
• 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. 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. Plenty of pitfalls in super()● verbose syntax — fragile on copy & paste :)● cant use: super(C, self)[0]● super(C) ≠ super(C, C)
• 35. ...but we should use super()● Its a standard.● Safer to multiple inheritance● If you mix with classic style, everything will be broken.