• Home
  • Publications
  • Subscribe
  • Crazy Python

    Over the time I spent with Python, I discovered some weird quirks and funny tricks you can do. Some of them are intentionally put in place by our Benevolent Dictator Emeritus Vacationing Indefinitely from the Language, some of them are just a manifestation of how poetic Python is.

    If you are looking for useful tips and tricks, these aren't the droids you are looking for.

    Hello World!

    Python is very effective language. In fact, it has one of the shortest Hello World! No functions needed.

    import __hello__ # Hello world!

    Zen of Python

    Another import trick, that not everybody knows, is Zen of Python.

    import this
    # The Zen of Python, by Tim Peters
    #
    # Beautiful is better than ugly.
    # Explicit is better than implicit.
    # Simple is better than complex.
    # Complex is better than complicated.
    # Flat is better than nested.
    # Sparse is better than dense.
    # Readability counts.
    # Special cases aren't special enough to break the rules.
    # Although practicality beats purity.
    # Errors should never pass silently.
    # Unless explicitly silenced.
    # In the face of ambiguity, refuse the temptation to guess.
    # There should be one-- and preferably only one --obvious way to do it.
    # Although that way may not be obvious at first unless you're Dutch.
    # Now is better than never.
    # Although never is often better than *right* now.
    # If the implementation is hard to explain, it's a bad idea.
    # If the implementation is easy to explain, it may be a good idea.
    # Namespaces are one honking great idea -- let's do more of those!

    If only more programmers lived by it.

    Antigravity

    Python comes with Batteries Included©. It just makes sense it also includes antigravity module.

    import antigravity
    Comic strip XKCD about Python antigravity module

    Braces

    If you don't like Python's syntax using whitespaces to denotate scopes, you can use curly brackets just like in C or Java. All you have to do, is import braces.

    from __future__ import braces

    Swapping variables

    If you know Java, you probably encountered an exercise to swap two integer values using only one line of code. This is one possible solution.

    int x = 100;
    int y = 19;
    x = x ^ y ^ (y = x);

    In Python you can do this much easier and with any variable type (and less semicolons).

    x = 100
    y = 19
    x, y = y, x
    # x: 19, y: 100

    Reversing a list

    This is a well known trick and it's probably one of the first thing someone told when they tried to convince you Python is the best language in the world. Reversing a list or a string in Python is super simple.

    s = 'Hello World!'
    s[::-1]
    # '!dlroW olleH'

    Copying a list

    As we saw, list slicing is very powerful. Another thing we can use it for is creating a shallow copy of a list.

    l = [1, 2, 3]
    c = l[:]
    c.append(4)
    # l: [1, 2, 3]
    # c: [1, 2, 3, 4]

    Thousands separator

    Reading long number literals can be tricky as you have to make sure you didn't miss any decimal. In Python you can make it easier for yourself and separate thousands with an underscore.

    seconds_in_year = 31_536_000 # same as 31536000

    Literal attributes

    As I explained in the article Power of metaclasses, everything is an object. That means you can access attributes and methods of any variable or literal, even strings and integers, using dot syntax.

    "string".upper() # STRING

    But with integers Python thinks you are using dot as a decimal separator, so you have to use a little trick.

    (42).__add__(5) # 47

    Boolean is an integer

    Bool type inherits from int which can sometimes lead to weird bugs.

    isinstance(False, int) #True
    5 + True # 6

    Caching of integers

    Speaking of integers, Python caches some integer values. The range changes between versions, but usually values between -5 a 256 are cached, values over 1000 are not cached.

    (2 + 5) is 7 # True
    (1000 + 1) is 1001 # False

    Interval comparison

    Great feature, that I miss in other languages, is an interval comparison. You can test if a value is within an interval using single expression.

    1 <= variable <= 100 # True if value is between 1 and 100

    Metaclasses

    Metaclasses are a huge topic which I explain thoroughly in article Power of metaclasses. It's very easy to abuse. For example, many programmers struggle with inheritance; they're not sure in which order methods are imported from parent classes. Why not make it easier for them and sort the inheritance tree alphabetically?

    class Library(type):
    	def mro(cls):
    		return sorted(
    			super().mro(),
    			key=lambda cls: cls.__name__
    		)
    
    class AClass(metaclass=Library):
    	def hello(self):
    		print('hello', 'A')
    
    class BClass(AClass):
    	def hello(self):
    		print('hello', 'B')
    
    class CClass(BClass):
    	def hello(self):
    		print('hello', 'C')
    
    print(CClass.mro())
    # [<class '__main__.AClass'>,
    #  <class '__main__.BClass'>,
    #  <class '__main__.CClass'>,
    #  <class 'object'>]
    CClass().hello() #hello A

    Try/Except/Finally/Else

    Even if you came to Python from different language, like me, you probably know about the optional else clause for loops.

    for i in get_list():
    	print(i)
    else:
    	print("no iterations")

    But you might not have know that you can use else also in exception handling.

    try:
    	print('executed first')
    except:
    	print('executed when exception happens')
    else:
    	print('executed when no exception happens')
    finally:
    	print('always executed at the end')

    Boolean operators

    Almost all beginner tutorials on conditions explain boolean operators something like this:

    The expression A and B is True if both A is True and B is True, and False if either is False. Computer Science Circles

    It's nice, simple and absolutely wrong explanation. Result of boolean operations in Python is not a boolean but False or one of the operands.

    result = 2 < 1 and 'string'
    print(result) # string
    # Result of "and" operand is the last value
    result = [1, 2] or 2 < 1
    print(result) # [1, 2]
    # Result of "or" operand is the first value that evaluates to True

    Returning from finally

    I wrote an extensive article about returning from finally before but it's still worth mentioning here. Code in finally is always executed, even if you already returned from your function. If you then return again from the finally block, it rewrites the original value.

    def test():
    	try:
    		return 'try'
    	finally:
    		return 'finally'
    
    print(test()) # finally

    That's enough craziness for today. If you have your own favorite crazy tricks in Python, send them to me using one of the links in the footer and I'll add them to the list.