Python

From miki
Revision as of 18:20, 9 April 2014 by Mip (talk | contribs) (→‎Reference)
Jump to navigation Jump to search

Links

Other versions of Python are available [1]
  • Nice example of generating / testing regex in Python (with nice / small test framework) [2]

Shell

Use iPy (ipython) to get an interactive shell with auto-completion, instant help...

%magic                    # Get help on %magic commands (%run,...)
?run                      # Get help on %run magic
%run script.py            # Run given script
%run -i script.py         # ... with inspect mode on
%run -i -e script.py      # ... ... and ignore sys.exit() call
!cmd                      # Run shell command 'cmd', for instance ...
!ls                       # ... List file in current directory

Reference

Basic

for i in range(10):
    print i                      # carriage return

for i in range(10):
    print i,                     # no carriage return
for key in d:                       # Loop over keys in dictionary d
for key, value in d.iteritems():    # Loop over keys and values in dictionary d

a = 'global'
def afunction():
    global a
    a = 'still using global'
    b = 'local'
import os.path
os.path.isfile(fname)            # True if fname exists and is a file

if not os.path.exists(directory):
    os.makedirs(directory)       # Create directory if does not exists

try:                             # Avoid race condition if directory created by another process
    os.makedirs(path)            # But we could fix solution above as well
except OSError:                  # This one always trigger an exception in nominal case
    if not os.path.isdir(path):  
        raise
                                  

s.upper()                        # string s to uppercase
', '.join(set_3)                 # Join a sequence

sys.argv, len(sys.argv)          # Argument list, number of arguments ([0] -> exec name)

# Sort based on object attribute
ut.sort(key=lambda x: x.count, reverse=True)   # To sort the list in place...
newlist = sorted(ut, key=lambda x: x.count, reverse=True)  # To return a new list, use the sorted() built-in function...

From stackoverflow [3],

Modules

import datetime
print datetime.datetime.today()  
print datetime.datetime.now()    # similar, but possibly more accurate
print datetime.date.now()        # date only

Advanced

mymodule = __import__('mymodule')          # Import module from string - see http://effbot.org/zone/import-string.htm

Tips

Simple HTTP Server

It's very easy to setup an ad-hoc HTTP server with Python. Just open a shell in a folder with some contents to share, and type:

python -m SimpleHTTPServer

More available at http://docs.python.org/2/library/internet.html (see BaseHTTPServer and CGIHTTPServer).

Detect interactive mode

References: [4], [5]

Started with First method Second method Third method Fourth method
import __main__ as main print hasattr(main, '__file__') def in_ipython(): try: __IPYTHON__ except NameError: return False else: return True import sys print hasattr(sys, 'ps1'): import sys print bool(sys.flags.interactive)
python mymod.py True - - -
python -i mymod.py True - - True
python then import mymod - - True -
ipython mymod.py True True - -
ipython -i mymod.py True True - -
ipython then run mymod.py True True - -
ipython then run -i mymod.py True True - -
ipython then import mymod - True - -
ipython -i then import mymod - True - -

Find duplicates in list

From stackoverflow [6]

import collections

def fastest():                         # 134 us - Fastest
    seen = set()
    seen_add = seen.add                                            # To avoid lookup 'add' ever time an item is inserted
    seen_twice = set( x for x in l if x in seen or seen_add(x) )   # adds all elements it doesn't know yet to seen and all other to seen_twice
    return list( seen_twice )                                      # turn the set into a list (as requested)

def compact():                         # 415 us
    return [x for x, y in collections.Counter(l).items() if y > 1]

def slowest():                         # 19.2 ms
    return list(set([x for x in l if l.count(x) > 1]))

Start post-mortem debugger on exception

From stackoverflow [7]

>>> import pdb
>>> pdb.pm()

Miscellaneous

Detect whether a variable is defined

Note it is bad practice to define a variable conditionally [8]. An interesting use case is to run code and define variable conditionally based on interactive status.

# Using try ... except
try: myvar
except NameError: print "variable 'myvar' IS defined"

# Using vars() / globals()
'myvar' in vars() or 'myvar' in globals()
# ...pedantic...
'myvar' in vars(__builtins__)

Traps

Frequent mistakes. Beware the snake can bite you!

Confuse a method and a property in a test
SOLUTION: Stick to a convention. Like always define methods like isxyyz() or hasabc() as methods. Note that defining them as property would raise an exception if used as a function, and hence might be safer.
if A.isdummy():            # This will fail isdummy is a property
if A.isdummy:              # Always True if isdummy is a method
Mix 0 with None in a sequence
Testing whether an element is defined is more difficult.
a = [0,None,None,None]
bool(a[0])           # --> False
bool(a[1])           # --> False !!! How can we tell them apart?
a[1] == None         # --> True      This works, but is unusual and likely bad practice
Mixing property and normal getter
SOLUTION: prefix all getter method with get, like getvalue()
b = a.prop           # Using a property, OR
b = a.getprop()      # Using a getter


Unicode

Set source file encoding

Add any of these lines [9]:

# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
Write the BOM

See [10]

import codecs

file = codecs.open("lol", "w", "utf-8")
file.write(u'\ufeff')                          # or use unicode name: u'\N{ZERO WIDTH NO-BREAK SPACE}'
file.close()

# Using https://docs.python.org/2/library/codecs.html#module-encodings.utf_8_sig
with codecs.open("test_output", "w", "utf-8-sig") as temp:
    temp.write("hi mom\n")
Handling unicode

Some recommends to always process unicode internally, and decode on input and encode on output [11]:

line = line.decode('utf-8')
# ...treat line as unicode...
print line.encode('utf-8')

But this is error prone. So another solution proposed is to redefine sys.stdout:

import sys
import codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)

An hackish way (not recommended):

# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
print u"åäö"