Python: The Dictionary Playbook

I so often come across various kinds of boilerplate code regarding dictionaries in Python, that I decided to show some of it here and share the more concise way of performing the same operations.
Presenting: The Dictionary Playbook.

image

Read More

You Can’t Handle the Truth!

I got a chance to review some other people’s Python code recently, and there’s one comment I almost always have to give, which is:

if x and if x is not None are not the same!
corollary: if not x and if x is None are also quite different, obviously.

This usually happens when someone assigns None to a variable (say, x) as a sentinel value, and then x may or may not be assigned to. The test is designed to check whether or not x was assigned to, or not.

When you do if x is None, you call the operator is, which checks the identity of x. None is a singleton in Python and all None values are also the exact same instance. When you say if x, something different happens. if expects a boolean, and assuming x is not a boolean, Python automatically calls x’s __nonzero__ method. i.e., if x is actually executed as if x.__nonzero__ (or bool(x)). __nonzero__ is pretty poorly named*, but it’s a method that evaluated a class as a boolean value. It’s one of Python’s Magic Methods. The confusing thing is, that bool(None) returns False, so if x is None, if x works as you expect it to. However, there are other values that are evaluated as False. The most prominent example is an empty list. bool([]) returns False as well. Usually, an empty list has a meaning that is different to None; None means no value while an empty list means zero values. Semantically, they are different. I guess people are just unaware of the semantic difference between the two ways to write the condition.

Here are some useful snippets to demonstrate:

Testing None

>>> x = None 
... if x:
...     print 'if x'
... if x is not None:
...     print 'if x is not None'

Testing an Empty List

>>> x = [] 
... if x:
...     print 'if x'
... if x is not None:
...     print 'if x is not None'
if x is not None

Testing a Normal Value

>>> x = 42 
... if x:
...     print 'if x'
... if x is not None:
...     print 'if x is not None'
if x
if x is not None

Testing a Custom Class

>>> class Foo(object): 
...     def __nonzero__(self):
...         print 'Foo is evaluated to a boolean!'
...         return True
...
... x = Foo()
... if x:
...     print 'if x'
... if x is not None:
...     print 'if x is not None'
Foo is evaluated to a boolean!
if x
if x is not None

* Fortunately, the folks working on Python had the sense to change this to __bool__ in Python 3.x!

Self Printing Programs in Python

Let’s talk about self printing programs (or, quines). A self printing program is, as is its name, self explanatory. Today I thought about how to implement a quine in Python, I whipped up a solution on my own and then posed the challenge to some people in the office. These are the results:

My Version 

s = r"print 's = r\"{0}\"'.format(s), '\n', s" 
print 's = r\"{0}\"'.format(s), '\n', s

This exemplifies a common way to implement a quine - the main problem is that you have to use some sort of function that prints. But of course, you also have to print that function, and so on. The way to deal with this is put the entire program in a string, except the assignment to that string, then print the assignment (where you can use the string itself to avoid explicitly writing it again, thus avoiding the recursion), and then the string.  Notice there’s a lot of playing with quotation marks. Next is a version that tries to solve this.

Using chr for Quotation Marks

a = "b = chr(97) + chr(32) + chr(61) + chr(32) + chr(34); b += a; print b + chr(34); print a"
b = chr(97) + chr(32) + chr(61) + chr(32) + chr(34); b += a; print b + chr(34); print a

This version (while a bit cumbersome) solves the quotation marks problem by just explicitly printing the ascii characters.

Using exec Instead of Repeating the print

s = r"print 's = r\"' + s + '\"' + '\nexec(s)'"
exec(s)

I really likes this version, as it mostly avoids repeating the code in the two lines.

The Smartass Approach

Well, the first person I introduced this challenge to, had a pretty wiseass, but overall, clever approach. He did this:

print open(__file__).read()

This works, and is pretty clever, but it obviously isn’t what quines are all about. It also wouldn’t work in an interactive shell.

The “Google” Way

After I got the above answers, I just had to google Python quines and see what comes up. A StackOverflow thread points out this (pretty cool) snippet:

_='_=%r;print _%%_';print _%_

It assigns to the variable _ a string which is contains the entire code, except for its own value which is replaced by a formatting instruction, and then print _ and feeds itself into its formatting. Looks obfuscated, but it’s pretty cool when you take a deeper look.

What else is there in Python?

We all use the else keyword in Python, usually accompanying if statement:

if x > 0: 
    print 'positive'
elif x < 0:
    print 'negative'
else:
    print 'zero'

 but Python has a few other uses to the else keyword that most people are unfamiliar with.

Read More

Cool Syntax and Weird Documentation - Fun with Scapy

I was looking for a way to parse TCP/IP packets in Python, when a friend recommended Scapy. Scapy is a nice python package that’s got a very cool interface using the “div” operator, and is used like so:

packet = IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
str(packet) # returns the packet's binary data 

which is pretty cool and creative. It makes the layers concept pretty visual. Now, I was looking for a way to parse packets, i.e., the other way around. So we were looking in scapy’s documentation. The section on “dissecting” seemed like it might be what we wanted, and here’s the introduction:

Dissecting

Layers are only list of fields, but what is the glue between each field, and after, between each layer. These are the mysteries explain in this section.

I ended up not needing to parse packets, but I did use it to generate TCP/IP packets, and I gotta say, it couldn’t be any easier. Go on, check it out. Their documentation also teaches Python.

Double Iteration in List Comprehension

Here’s something I didn’t know possible in Python: iteration over more than one iterable in a list comprehension:

>>> seq_x = [1, 2, 3, 4]
>>> seq_y = 'abc'
>>> [(x,y) for x in seq_x for y in seq_y]
[(1, 'a'), 
(1, 'b'),
(1, 'c'),
(2, 'a'),
(2, 'b'),
(2, 'c'),
(3, 'a'),
(3, 'b'),
(3, 'c'),
(4, 'a'),
(4, 'b'),
(4, 'c')]

Cool, isn’t it? It’s equivalent to the following snippet:

>>> result = [] 
... for x in seq_x:
...     for y in seq_y:
...         result.append((x,y))
>>> result
[(1, 'a'),
(1, 'b'),
(1, 'c'),
(2, 'a'),
(2, 'b'),
(2, 'c'),
(3, 'a'),
(3, 'b'),
(3, 'c'),
(4, 'a'),
(4, 'b'),
(4, 'c')]

It also supports both “if” statements and referencing the outer iterator from the inner one, like so:

>>> seq = ['abc', 'def', 'g', 'hi'] 
... [y for x in seq if len(seq) > 1 for y in x if y != 'e']
['a', 'b', 'c', 'd', 'f', 'g', 'h', 'i']

This is equivalent to the snippet:

>>> result = [] 
... for x in seq:
...     if len(seq) > 1:
...         for y in x:
...             if y != 'e':
...                 result.append(y)
... result ['a', 'b', 'c', 'd', 'f', 'g', 'h', 'i']

The thing you should notice here, is that the outer loop is the first ‘for’ loop in the list comprehension. This was a little confusing for me at first because when I nest list comprehensions it’s the other way around.

To read more about this feature, check out this StackOverflow thread or the Python Manual.

Implementing the Singleton Pattern in Python

TL;DR: Use metaclasses - see #4 on the list

I recently heard some people at work talking about ways to implement the Singleton pattern in Python. I’m fairly new to Python, and for me, the most elegant Singleton definition would be in Java:

enum MySingleton {
    INSTANCE;

    // methods, members, etc.
}

and that’s it! Use MySingleton.INSTANCE and you got yourself a singleton. Well, in Python it’s more cumbersome (enums in Java are pretty awesome and hard to compete with, even with Python’s general awesomeness). I suggested using a singleton metaclass, but it was turned down for being too complicated. Well, let’s take a look at some other implementation ideas I’ve heard, and we’ll look at the metaclass alternative at the end:

  1. Provide a get_instance method and make __init__ throw (fine, fine, raise) an exception if it was called twice:
     class MySingleton(object):
        INSTANCE = None

        def __init__(self):
            if self.INSTANCE is not None:
                raise ValueError("An instantiation already exists!")
            # do your init stuff

        @classmethod
        def get_instance(cls):
            if cls.INSTANCE is None:
                cls.INSTANCE = MySingleton()
            return cls.INSTANCE

    Cons: Using get_instance is ugly and non-intuitive.
  2. Implementing an inner class as your ‘main class’ and the external one as a wrapper:
     class MySingleton:
        """ A python singleton """

        class __impl:
            """ Implementation of the singleton interface """
            # implement your stuff in here
            pass

        # storage for the instance reference
        __instance = None

        def __init__(self):
            """ Create singleton instance """
            # Check whether we already have an instance
            if MySingleton.__instance is None:
                # Create and remember instance
                MySingleton.__instance = MySingleton.__impl()

            # Store instance reference as the only member in the handle
            self.__dict__['_Singleton__instance'] = MySingleton.__instance

        def __getattr__(self, attr):
            """ Delegate access to implementation """
            return getattr(self.__instance, attr)

        def __setattr__(self, attr, value):
            """ Delegate access to implementation """
            return setattr(self.__instance, attr, value)


    Cons: This implementation is definitely not beautiful. Also, it prevents users from subclassing the business logic class.

  3. Implementing a ‘singleton’ decorator for classes:
     def singleton(cls):
        instances = {}

        def getinstance():
            if cls not in instances:
                instances[cls] = cls()
            return instances[cls]

        return getinstance

    @singleton
    class MyClass:
        ...

    Cons: This code turns MyClass into a factory function, so you can’t subclass it or use ‘isinstance’, etc.
  4. Implementing a SingletonType metaclass:
     class SingletonType(type):

        def __call__(cls, *args, **kwargs):
            try:
                return cls.__instance
            except AttributeError:
                cls.__instance = super(SingletonType, cls).__call__(*args, **kwargs)
                return cls.__instance


    class MySingleton(object):
        __metaclass__ = SingletonType

        # ...

    Cons: Other than some people considering metaclasses to be black magic, none that I can think of (besides general ‘singletons are evil’ complaints).

Sources