1 / 56

Composability through Multiple Inheritance

Composability through Multiple Inheritance. A drama in Three Acts by Łukasz Langa. Act I: Exposition. where we meet our characters and the world they live in. Composability. Compositionality. Unix pipes. $ ps aux | grep celery | grep -v grep | awk '{print $2}' | xargs kill -9. Unix pipes.

gurit
Télécharger la présentation

Composability through Multiple Inheritance

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Composabilitythrough Multiple Inheritance A drama in Three Actsby Łukasz Langa

  2. Act I: Exposition where we meet our characters and the world they live in

  3. Composability

  4. Compositionality

  5. Unix pipes $ ps aux | grep celery | grep -v grep |awk '{print $2}' | xargs kill -9

  6. Unix pipes $ ps aux | grep celery | grep -v grep |awk '{print $2}' | xargs kill -9

  7. Unix pipes $ command1 | command2 | command3 | ...

  8. Godtfred Kirk Christiansen

  9. Joe Armstrong

  10. Joe Armstrong grep REGEX <file >matches

  11. Quality

  12. Robert M. Pirsig

  13. Jamie Zawinski

  14. Composability Compositionality Quality

  15. Act II: Rising Action where we learn how inheritance in Python works

  16. Ifyouuseold-style classes You’re gonna have a badtime

  17. Method Resolution Order >>> class A(object): ... pass ... ... >>> A.mro() [<class '__main__.A'>, <type 'object'>]

  18. Method Resolution Order

  19. Method Resolution Order >>> class A(object): pass ... >>> class B(object): pass ... >>> class AB(A, B): pass ...

  20. The Diamond Problem • AB

  21. The Diamond ”Problem” • AB

  22. The Diamond ”Problem” >>> class A(object): pass ... >>> class B(object): pass ... >>> class AB(A, B): pass ... >>> AB.mro() [<class '__main__.AB'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]

  23. Method Resolution Order >>> class A(object): ... def say(self, what): ... return what + 'a’ ... >>> class B(object): ... def say(self, what): ... return what + 'b’ ... >>> class AB(A, B): pass ... >>> class BA(B, A): pass ... >>> AB().say('hello:') 'hello:a' >>> BA().say('hey:') 'hey:b'

  24. CooperativeInheritance class A(object): def __init__(self, arg_a): self.arg_a = arg_a class B(object): def __init__(self, arg_b): self.arg_b = arg_b class AB(A, B): def __init__(self, arg_a, arg_b): # ???

  25. CooperativeInheritance class A(object): def __init__(self, arg_a): self.arg_a = arg_a class B(object): def __init__(self, arg_b): self.arg_b = arg_b class AB(A, B): def __init__(self, arg_a, arg_b): A.__init__(self, arg_a) B.__init__(self, arg_b)

  26. CooperativeInheritance class AB(A, B): def __init__(self, arg_a, arg_b): A.__init__(self, arg_a) B.__init__(self, arg_b) >>> ab= AB('a', 'b') >>> ab.arg_a 'a' >>> ab.arg_b 'b'

  27. CooperativeInheritance class AB(A, B): def __init__(self, arg_a, arg_b): A.__init__(self, arg_a) B.__init__(self, arg_b) class C(D, AB): def __init__(self, arg_c): D.__init__(self) AB.__init__(self, *arg_c.split('.', 1)) >>> c=C('1.0') >>> c.arg_a '1' >>> c.arg_b '0’

  28. CooperativeInheritance class AB(A, B): def __init__(self, arg_a, arg_b): A.__init__(self, arg_a) B.__init__(self, arg_b) class C(D, AB): def __init__(self, arg_c): D.__init__(self) AB.__init__(self, *arg_c.split('.', 1)) >>> C.mro() [<class '__main__.C'>, <class '__main__.D'>, <class '__main__.AB'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]

  29. CooperativeInheritance class AB(A, B): def __init__(self, arg_a, arg_b): A.__init__(self, arg_a) B.__init__(self, arg_b) class D(A): def __init__(self): A.__init__(self, 'd') class C(D, AB): def __init__(self, arg_c): D.__init__(self) AB.__init__(self, *arg_c.split('.', 1))

  30. CooperativeInheritance A.__init__(self, arg_a)  super(AB, self).__init__(arg_a) class AB(A, B): def __init__(self, arg_a, arg_b): A.__init__(self, arg_a) B.__init__(self, arg_b) class C(D, AB): def __init__(self, arg_c): D.__init__(self) AB.__init__(self, *arg_c.split('.', 1)) >>> C.mro() [<class '__main__.C'>, <class '__main__.D'>, <class '__main__.AB'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]

  31. CooperativeInheritance class AB(A, B): def __init__(self, arg_a, arg_b): super(AB, self).__init__(arg_a=arg_a, arg_b=arg_b) class D(A): def __init__(self): super(D, self).__init__(arg_a='d') class C(D, AB): def __init__(self, arg_c): super(C, self).__init__( *arg_c.split('.', 1))

  32. CooperativeInheritance class D(A): def __init__(self): super(D, self).__init__(arg_a='d') class C(D, AB): def __init__(self, arg_c): super(C, self).__init__( *arg_c.split('.', 1)) >>> C('1.0') Traceback (most recent call last): File "<input>", line 1, in <module> File "mrosuper.py", line 27, in __init__ super(C, self).__init__(*arg_c.split('.', 1)) TypeError: __init__() takes exactly 1 argument (3 given)

  33. CooperativeInheritance class D(A): def __init__(self): super(D, self).__init__(arg_a='d') class C(D, AB): def __init__(self, arg_c): super(C, self).__init__( *arg_c.split('.', 1)) >>> C('1.0') Traceback (most recent call last): File "<input>", line 1, in <module> File "mrosuper.py", line 27, in __init__ super(C, self).__init__(*arg_c.split('.', 1)) TypeError: __init__() takes exactly 1 argument (3 given)

  34. class A(object): def __init__(self, arg_a, **kwargs): self.arg_a = arg_a super(A, self).__init__(**kwargs) class B(object): def __init__(self, arg_b, **kwargs): self.arg_b = arg_b super(B, self).__init__(**kwargs) class AB(A, B): def __init__(self, arg_a, arg_b, **kwargs): super(AB, self).__init__(arg_a=arg_a, arg_b=arg_b, **kwargs) class D(A): def __init__(self, **kwargs): super(D, self).__init__(arg_a='d', **kwargs) class C(D, AB): def __init__(self, arg_c, **kwargs): super(C, self).__init__(*arg_c.split('.', 1), **kwargs)

  35. class A(object): def __init__(self, arg_a, **kwargs): self.arg_a = arg_a super(A, self).__init__(**kwargs) class B(object): def __init__(self, arg_b, **kwargs): self.arg_b = arg_b super(B, self).__init__(**kwargs) class AB(A, B): def __init__(self, arg_a, arg_b, **kwargs): super(AB, self).__init__(arg_a=arg_a, arg_b=arg_b, **kwargs) class D(A): def __init__(self, **kwargs): super(D, self).__init__(arg_a='d', **kwargs) class C(D, AB): def __init__(self, arg_c, **kwargs): super(C, self).__init__(*arg_c.split('.', 1), **kwargs)

  36. class A(object): def __init__(self, arg_a, **kwargs): self.arg_a = arg_a super(A, self).__init__(**kwargs) class B(object): def __init__(self, arg_b, **kwargs): self.arg_b = arg_b super(B, self).__init__(**kwargs) class AB(A, B): def __init__(self, arg_a, arg_b, **kwargs): super(AB, self).__init__(arg_a=arg_a, arg_b=arg_b, **kwargs) class D(A): def __init__(self, **kwargs): super(D, self).__init__(arg_a='d', **kwargs) class C(D, AB): def __init__(self, arg_c, **kwargs): super(C, self).__init__(*arg_c.split('.', 1), **kwargs)

  37. THIS SHIT IS HARD

  38. class A(object): def __init__(self, arg_a, **kwargs): self.arg_a = arg_a super(A, self).__init__(**kwargs) class B(object): def __init__(self, arg_b, **kwargs): self.arg_b = arg_b super(B, self).__init__(**kwargs) class AB(A, B): def __init__(self, arg_a, arg_b, **kwargs): kwargs['arg_a'], kwargs['arg_b'] = arg_a, arg_b super(AB, self).__init__(**kwargs) class D(A): def __init__(self, **kwargs): kwargs['arg_a'] = 'd' super(D, self).__init__(**kwargs) class C(D, AB): def __init__(self, arg_c, **kwargs): kwargs['arg_a'], kwargs['arg_b'] = arg_c.split('.', 1) super(C, self).__init__(**kwargs)

  39. It’sstilldifferent! >>> c=C('1.0') >>> c.arg_a u'd' >>> c.arg_b u'0'

  40. CooperativeInheritance • Don’tomitsuper(C, self).__init__() evenifyourbaseclassisobject • Don’tassumeyouknowwhatargumentsyou’regoing to get • Don’tassumeyouknowwhatargumentsyoushould pass to super • always pass allargumentsyoureceivedon to super • ifclassescantakedifferingarguments, alwaysaccept**kwargs

  41. Ifyou mix Class.__init__ and super() You’re gonna have a badtime

  42. Mixins Not meant for instantiation on theirown Enhanceclasses with independent functionality Not a form of specialisation but collection of functionality Likeinterfaces with built-in implementation Veryreusableiforthogonal to the maintype

  43. Interlude Django ORM inheritance model sucks

  44. The Diamond Problem • M4

  45. Polymorphism

  46. Liskovsubstitutionprinciple

  47. Act III: The Climax

More Related