Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2017 - Henry Chen - Taking the __magic__ out of Python classes

PyBay
August 11, 2017

2017 - Henry Chen - Taking the __magic__ out of Python classes

A peek into the internals of Python classes. Including the world's quickest introduction to metaclasses.

Video: https://youtu.be/d3G3glxPt5g

PyBay Conference: https://pybay.com

PyBay

August 11, 2017
Tweet

More Decks by PyBay

Other Decks in Programming

Transcript

  1. Taking the magic out of Python classes Henry Chen Let's

    make a cat. In [1]: class Cat(object): pass grumpy = Cat() grumpy Oops. Forgot to include cat-like features. But we can add on. In [2]: Cat.sound = 'meow' def some_function(self): print self.sound Cat.speak = some_function grumpy.speak() Let's turn Grumpy into a dog. Out[1]: <__main__.Cat at 0x10df1c3d0> meow
  2. In [3]: class Dog(object): sound = 'woof' speak = some_function

    grumpy.__class__ = Dog grumpy.speak() Grumpy is not happy about being a dog. In [4]: grumpy.sound = 'meh' grumpy.speak() If Grumpy is an instance of Dog... In [5]: type(grumpy) then Dog must be an instance of ... type In [6]: type(Dog) type is just a class whose instances are other classes. Since it's a class, we can subclass type. woof meh Out[5]: __main__.Dog Out[6]: type
  3. In [7]: class MetaCat(type): def __repr__(cls): return ' ' def

    factory(cls): # not available on the Cat instance! return cls() Class definition is just fancy syntax for instantiating a metaclass. In [8]: class FancyCat(Cat): __metaclass__ = MetaCat # Py2 syntax type(FancyCat) In [9]: FancyCat In [10]: grumpy.__class__ = FancyCat grumpy.speak() grumpy In [11]: FancyCat.factory() Out[8]: __main__.MetaCat Out[9]: meh Out[10]: < at 0x10df1c3d0> Out[11]: < at 0x10df1c090>
  4. In [12]: grumpy.factory() # this does not work, yay! Why

    metaclass? It's fun. What else are you gonna do? It unifies classes and objects. (Actually useful stuff.) tl;dr Classes are dynamic structures. Classes are instances. Be stupid! Silly, useless code is the best way to learn! [email protected] @SoylentBleen -------------------------------------------------------------------- ------- AttributeError Traceback (most recent cal l last) <ipython-input-12-1710632cd721> in <module>() ----> 1 grumpy.factory() # this does not work, yay! AttributeError: 'FancyCat' object has no attribute 'factory'