Decorators: A neat way to modify functions

In Python, decorators are a construction that help reduce boilerplate code, enhance the maintainability of our code and address the separation of concerns. A decorator is a statement just above the function it decorates. Here's a simple example so you can understand what I mean:

def heading1(func):
    """
    Define the decorating function - this wraps the return value of the 
    string in html heading tags. Don't actually write html like this - it is a
    silly idea.
    """
    def wrapper(*args, **kwargs):
        return "<h1>" + func(*args, **kwargs) + "</h1>"
    return wrapper

# Use the decorator here, before the function definition.
@heading1
def subject():
    return "Decorators: A neat way to modify functions"

print subject()
# Output is "<h1>Decorators: A neat way to modify functions</h1>"

That seems very neat, but this is a simple way of writing something complicated, so there are some kinks to iron out. The first is that in a generally applicable decorator, the decorating function must be able to accept an arbitrary argument list (meaning any arrangement of arguments and keyword arguments). The issue with this is that the resulting decorated function takes on the signature of the decorating function, so introspection of the function tells you that it accepts ...

Read more

Batch file comments

In Windows batch files, you can use a double-colon (::) as a comment. I've just spend a few hours trying to figure out why my batch file says, "The syntax of the command is incorrect." when I run it. The answer? I've got a :: comment as the last statement after a group of IF statements. Obscure? Yes. Flaky? Certainly. Oh — hang on, it might be because I've got the :: before a for statement. For some arrangements of the :: comment, I'm also getting "The system cannot find the drive specified."

:: is a bad, bad thing. My advice: Stick to REM

Read more

Obscure python urllib2 proxy gotcha

This is going to be very obscure, technical and humourless1, so unless you suspect your environment-set http proxy is messing with your python, you can stop reading now.

This is actually two problems, and three solutions.

Problem:
My python script bombs out with:

File "c:\Python23\lib\urllib2.py", line 506, in proxy_open
    if '@' in host:
TypeError: iterable argument required

Solution:
Your ‘http_proxy’ environment variable must include ‘http://’ at the start.

Problem:
But why’s it happening in the first place? I’m not even using the environment-set proxy – I’m defining my own, thus:

proxy_handler = urllib2.ProxyHandler({'http': 'http://myproxy.net:3128'})
opener = urllib2.build_opener()
opener.add_handler(proxy_handler)

Solution:
Ah! But urllib2.build_opener() has a set of default handlers, one of which is a proxy handler. Guess what the default behaviour of the proxy handler is, when you don’t give it a proxy url? It gets it from the environment.

So you’re ending up with two proxy handlers. The default one gleaned from the environment, and your custom one. It seems that it only uses the custom one (try it using Wireshark) but it still processes the environment one. So if the format of the environment ...

Read more