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

Presentation on theme: "Act I: Exposition where we meet our characters and the world they live in."— Presentation transcript:

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

Composability

Compositionality

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

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

Unix pipesUnix pipes \$ command1 | command2 | command3 |...

Godtfred Kirk ChristiansenGodtfred Kirk Christiansen

Joe ArmstrongJoe Armstrong

grep REGEX matches

Quality

Robert M. PirsigRobert M. Pirsig

Jamie ZawinskiJamie Zawinski

Quality Composability Compositionality

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

If you use old-style classes Youre gonna have a bad time

Method Resolution OrderMethod Resolution Order >>> class A(object):... pass... >>> A.mro() [, ]

Method Resolution OrderMethod Resolution Order object A

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

The Diamond ProblemThe Diamond Problem object AB AB

The Diamond ProblemThe Diamond Problem object AB AB

The Diamond ProblemThe Diamond Problem >>> class A(object): pass... >>> class B(object): pass... >>> class AB(A, B): pass... >>> AB.mro() [,,, ]

Method Resolution OrderMethod 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'

Cooperative InheritanceCooperative Inheritance 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): # ???

Cooperative InheritanceCooperative Inheritance 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)

Cooperative InheritanceCooperative Inheritance 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'

Cooperative InheritanceCooperative Inheritance 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

Cooperative InheritanceCooperative Inheritance 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() [,,,,, ]

Cooperative InheritanceCooperative Inheritance 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))

Cooperative InheritanceCooperative Inheritance 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() [,,,,, ] A.__init__(self, arg_a) super(AB, self).__init__(arg_a)

Cooperative InheritanceCooperative Inheritance 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))

Cooperative InheritanceCooperative Inheritance 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 " ", line 1, in File "mrosuper.py", line 27, in __init__ super(C, self).__init__(*arg_c.split('.', 1)) TypeError: __init__() takes exactly 1 argument (3 given)

Cooperative InheritanceCooperative Inheritance 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 " ", line 1, in File "mrosuper.py", line 27, in __init__ super(C, self).__init__(*arg_c.split('.', 1)) TypeError: __init__() takes exactly 1 argument (3 given)

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)

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)

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)

THIS SHIT IS HARD

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)

Its still different!Its still different! >>> c=C('1.0') >>> c.arg_a u'd' >>> c.arg_b u'0'

Cooperative InheritanceCooperative Inheritance Dont omit super(C, self).__init__() even if your base class is object Dont assume you know what arguments youre going to get Dont assume you know what arguments you should pass to super always pass all arguments you received on to super if classes can take differing arguments, always accept **kwargs

If you mix Class.__init__ and super() Youre gonna have a bad time

Mixins Not meant for instantiation on their own Enhance classes with independent functionality Not a form of specialisation but collection of functionality Like interfaces with built-in implementation Very reusable if orthogonal to the main type

Interlude Django ORM inheritance model sucks

The Diamond ProblemThe Diamond Problem M1 M2M3 M4

Polymorphism M1 M2M3M4

Liskov substitution principleLiskov substitution principle M1 M2M3M4

Act III: The Climax

Yep, here comes the demo.

And by the wayAnd by the way Just so you know.

Jamie ZawinskiJamie Zawinski

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

Similar presentations