Some notes on a few slightly quirky features of python that I (and everyone) ought to take note of.
These are fairly well known, but still don’t seem to be used as often as they could be. Users of older versions often prefer the use of map or filter, but a list comprehension helps keep things to one line while retaining natural ordering.
map
filter
A simple example of a list comprehension is
print([ i for i in range(10) ])
which generates the list output
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
This is similar to the for loop
_ = [] for i in range(10): _.append(i) print(_)
We are by no means limited to a simple identity mapping
print([ i**i for i in range(10) ]) [1, 1, 4, 27, 256, 3125, 46656, 823543, 16777216, 387420489]
Consider the code snipet
def print_name(func): def new_func(*args,**kwargs): print(func.__name__) func(*args,**kwargs) return new_func @print_name def print_list(n): print([i for i in range(n)]) print_list(5)
This outputs the following:
print_list [0, 1, 2, 3, 4]
Effectively the line beginning with @ causes the function print_list to be replaced with print_name(print_list). Decorators have a number of uses: Firstly they allow clean code by “redefining” function names on the line before they are created, rather than at the bottom of (potentially) long code Secondly, and more practically for logging, profiling or debugging purposes.
print_list
print_name(print_list)
To (mis)-quote from the original PEP343 the python code snippet
with foo as bar print(bar())
translates as something like
_ = (foo) bar = type(_).__enter__(_) flag = True try: try: print(bar()) except: flag = False if not type(_).__exit__(_, *sys.exc_info()):): raise finally: if flag: type(_).__exit__(_, None, None, None)
This rather dense block of logic efficiently wraps a lot of convenient library operations in which an object is created and then destroyed. For example, the new, sexy way of openning files:
with open("myfile.txt" as f" print(f.read())
This automagically deals with closing the file at the moment we leave the indented block, which is exactly when it should pass out of scope.