Ravings about Programming and Philosophy
In a [previous post](/post/reclaiming-enums) we saw that C-style enum syntax can be valid in Python using tracer tricks; but there's a much cleaner way in Python 3.
More Context Manager
In the [previous post](/post/deconstructing-context-managers) we saw what context managers are and how they work. In this one, we're going to use our new gained knowledge and write us some new context managers.
Deconstructing Context Managers
Context managers are a fancy name for a simple concept: running something before and after a segment of code. As simple as it is, this concept is also quite powerful, and can make your code much cleaner. Before we dive into the new stuff, let's understand what they are and how they work.
The Hello World Experience
Can you write a program that prints "Hello, world!" in C? This was the first exercise I was given in the military. I had a B. Sc. degree in mathematics and computer science, so naturally I thought I could: but I was wrong. So I fixed my code, but I was wrong again. And again. This is my Hello World experience.
Selfless Classes, Godless Hacks
In the [previous post](/post/selfless-classes), we managed to get Python classes working without adding ``self`` to their signatures, but we kind of polluted the global namespace and made a mess in the process. This time, we're going to use much darker magic, and rewrite function code on the fly. Viewer discretion is advised.
Python is a really cool language: it's clear, concise and beautiful. Not a single feature is surplus, not a single word is unnecessary... Except that whole ``self`` thing; what's the about? Do we really have to add this parameter to every signature of every method? Can't we just have it there automatically, like in any other object-oriented programming language out there?
The story behind a cool Bash autocompletion framework implemented in Python, including some not-very-funny jokes, an actually-quite-useful product, and a script that runs in both Bash and Python.
This example is actually the most useful, but it's also the most boring, so I kept it for last. It's a handy decorator to trace function execution, which is especially useful in catching Heisenbugs in production.
Taming Class Scopes
OK, That's a weird one, but it's actually quite handy: say you're using classes for configurations, and want to nest them like so: ```python class config: root = '/app/' class log: path = root + 'log.txt' ``` Turns out that for some obscure reason, scoping doesn't work the way you'd expect it to when it comes to classes: this code ``NameError``s because ``name 'root' is not defined``. Unless...
Taming Class Attributes
Once upon a time, we needed ordered class attributes. That is, given: ```python class A: x = 1 y = 2 z = 3 ``` We needed ``['x', 'y', 'z']``. "That's easy!" you exclaim; and indeed it is, in Python 3.6. "Well, it was possible before that, too!" you retaliate; and indeed it was, since Python 3.0. But what about *before* that? Can you make this code work in Python 2.7? ```python @ordered() class A: x = 1 y = 2 z = 3 assert A._order == ['x', 'y', 'z'] ```
Do you ever miss the way we used to write C-style enums in the good old days? Yeah, neither do I. But what if I told you this is valid Python code: ```python @cenum() class A: a b c = 10 d assert A.a == 0 assert A.b == 1 assert A.c == 10 assert A.d == 11 ```
The tracer is a wicked cool Python feature that's often overlooked, because it's so... well, wicked. In this series, we learn to use it (which takes about 12 seconds), and then do some really crazy stuff with it.
The Plugin Design Pattern
People sometimes say there are no design patterns in Python; I don't agree. Take the Plugin design pattern, for example: rethinking configurations as code, and having the operations division write actual Python that's then plugged into the system, can really boost your product.