Descriptors, Decorators, Metaclasses--Python's "Black Magic"?.notes

Saturday, March 26, 2005

TITLE OF PAPER: Descriptors, Decorators, Metaclasses--Python's "Black Magic"?
URL OF PRESENTATION: PDF of the slides is at; will be on sometime next week
PRESENTED BY: Alex Martelli
REPRESENTING: _name_of_the_company_they_represent_

DATE: 3/24/2005
LOCATION: Marvin Theater

{If you've contributed, add your name, e-mail & URL at the bottom}
This talk focuses on stuff in the Python Cookbook, 2nd edition

    the key infrastructure of Python's OOP
    attribute access (get, set, delete) ->
        search class/superclasses dicts for name
        if suitable descriptor found, deletegate
    all descriptors have method __get__
    if also has __set__, data descriptor (aka override descriptor)
        meaning: class overrides instance
    otherwise, non-date/non-override desc.

[example spelling out what happens behind the scenes when you do foo.fred = 5 or x = foo.fred]

What's a descriptor? Things that have __get__ and __set__?--Erik

so foo has a __get__ and __set__, not the class that contains foo?
Yes, that would be one way to do it.

Poor man's approach to currying: only works with one arg at a time, and it has to be the
    first one:
        def adder(x, y):
            return x + y
        add32 = adder.__get__(32)
        x = add32(3)
        x is 35

(Although there's nothing preventing you from chaining to add multiple args)

Can you give an example?

    def add(a,b,d):
        return a+b+c
    add3 = add.__get__(3)
    add5 = add3.__get__(2)

Ah. Rock my socks.

If you define a property on a class using property() and then derive a subclass from it that overrides a function you passed to property(), the subclass will still use the superclass's function, since the resolution happenswhen you call property().

    [a decorator that makes sure default args are always fresh]
    [one that prints a running trace each time a function is called]
    [logging is a very typical application that I've seen in other contexts]
    [locking was also mentioned]
    /Every/ class statement uses a metaclass, just usually "type".
    When exec'ing "class":
        1. Exec class body
        2. Identifcy metaclass
        WTH is a descriptor?!?!

The code behind a class call:

    bunch = type('bunch', (), ('foo':23)) (syntax possibly wrong)
    class bunch(object):

    Why a metraclass?
        Dynamically add methods, like accessors to private instance vars.
        Override __new__ to screw with __slots__, which you can't change later.
    You can define classes entirely in data pulled from a database.

    Metaclass conflicts
        Cases where there's no clear leaf node and python is not able to resolve
            the base class to pull from.

    """Boilerplate is evil""" If you're writing something more than three times,
    look for some way to factor it out.

I've got to run off to the next talk; feel free to rehost this. :-)  I'd have to understand it.

REFERENCES: {as documents / sites are referenced add them below}

"The general rule of programming is to use as much power as you need and no
    more."--Alex Martelli

CONTRIBUTORS: {add your name, e-mail address and URL below}
Erik Rose <>
Eric Soroos <>

E-MAIL BOUNCEBACK: {add your e-mail address separated by commas }

A headline (like a field in a database) will be CAPITALISED
    This differentiates from the text that follows
A variable that you can change will be surrounded by _underscores_
    Spaces in variables are also replaced with under_scores
    This allows people to select the whole variable with a simple double-click
A tool-tip is lower case and surrounded by {curly brackets / parentheses}
    These supply helpful contextual information.

Copyright shared between all the participants unless otherwise stated...