Python Idioms
Python Idioms
def render(self):
raise NotImplementedError()
@staticmethod
def register(name):
def decorator(cls):
macros[name] = cls
return cls
return decorator
@staticmethod
def by_name(name):
return Macro.macros.get(name)
A Plugin
@Macro.register(‘RecentChanges’)
class RecentChangesMacro(Macro):
def render(self):
return ‘render all changes’
Heavy Functions
@app.route(‘/users/’)
class Users(Controller):
def get(self):
return the list of users
def post(self):
return create a new user instead
@app.route(‘/users/<id:user_id>’, methods=[‘GET’])
def show_user(request, user_id):
return show the user
Creating Instances
def to_dict(thing):
return dict((k, v) for k, v in thing.__dict__.iteritems()
if not k.startswith(‘_’))
@to_dict
class Settings(object):
DEBUG = True
APPLICATION_NAME = ‘Testing’
SUBTITLE = ‘Python is a cool thing’
The Funny Descriptor
The Funny Descriptor
No n - Da t a
You all used it
>>> class Foo(object):
... def foo(self):
... pass
...
>>> Foo.foo.__get__
<method-wrapper '__get__' of instancemethod object at
0x1004551e0>
>>> request.args
MultiDict({‘foo’: u’bar’})
# the request arguments were now parsed and stored
>>> request.args
MultiDict({‘foo’: u’bar’})
# this returns the very same object as above but no
# function is called any more. Magic?
It’s a monkeypatch
_missing = object()
class cached_property(object):
class AcceptMixin(object):
@cached_property
def accept_mimetypes(self):
return parse_accept_header(
self.environ.get('HTTP_ACCEPT'), MIMEAccept)
@cached_property
def accept_charsets(self):
return parse_accept_header(
self.environ.get('HTTP_ACCEPT_CHARSET'),
CharsetAccept)
Abstract Base Classes
Not just inheritance
>>> from collections import Iterator
>>> class Foo(object):
... def __iter__(self):
... return self
... def next(self):
... return 42
...
>>> foo = Foo()
>>> isinstance(foo, Iterator)
True
>>> foo.next()
42
>>> foo.next()
42
But inheritance too
from collections import Mapping
class Headers(Mapping):
def __len__(self):
return len(self._headers)
def __iter__(self):
return (key for key, value in self._headers)
And it’s pretty sweet
texture = Texture.from_file(‘textures/grass.png’)
with texture:
draw_all_quads()
with Matrix(), \
Rotation(45.0, 1, 0, 0), \
Scale(0.5, 0.5, 0.5), \
texture:
draw_my_object()
Exhibit B
with test_request_context():
# setup a fake request context for testing purposes
# for the duration of this block here.
Exhibit C
with my_log_handler:
# everything that is logged here, is handled by
# “my_log_handler”
warning(‘This is pretty nifty’)
Exhibit D
try:
...
except:
...
try:
...
except Exception:
...
Going Meta (the AST)
What’s the AST?
@macro
def assign(variable, value):
variable = value
def testing():
assign(variable_name, 42)
return variable_name
Magic is the word
@macro
def assign(variable, value):
variable = value
def testing():
variable_name = 42
return variable_name
Remember
def counter(initial=0):
value = initial - 1
def count():
nonlocal value
value += 1
return value
return count
Python 3
>>> a, *b = [1, 2, 3, 4]
>>> a
1
>>> b
[2, 3, 4]