Introduction to Python

Introduction

Python is an excellent, cross-platform, object-oriented interpreted language. Besides ease of use, its main characteristic is that it enforces indentation (don't indent, and the program won't run.)

As of Septembre 2004, there are weaknesses to be aware of if you intend to use Python to write GUI apps for Windows, though:

Setup

At least three distributions of Python are currently available for the Windows platform (PythonWare used to be yet another package, but it's been deprecated):

If you only need a basic distribution, try out Tiny Python.

The "import" statement looks for module files in the directories specified in the $PYTHONPATH environment variable. If the named module isn't found in these directories, it returns an error. The first time Python imports a module, it automatically compiles the module as saves it as bytecode; this bytecode file has the same name as the module file, but ends in a .pyc extension. These .pyc files are automatically recompiled if the module changes in any way.

"On Windows, you can also use extension .pyw and interpreter program pythonw.exe instead of .py and python.exe. The w variants run Python without a text-mode console, and thus without standard input and output. These variants are appropriate for scripts that rely on GUIs. You normally use them only when the script is fully debugged, to keep standard output and error available for information, warnings, and error messages during development."

If you are using UltraEdit as your favorite editor, here's the section to add in UE's wordfile.txt to handle Python documents.

Compiling

An easy and satisfactory way to distribute your Python script on a Windows host is to compile it with Py2exe (which analyses your script, and tries to extract all the required modules into a ZIP file), and combine the different files using either a standard installer like InnoSetup or NSIS, or combine all the files into the main EXE generated by py2exe using PE Bundle which will extract those extra files at runtime transparently:

  1. Install py2exe, and write a setup script (call it setup.py):

    from distutils.core import setup
    import py2exe

    setup(console=["myapp.py"])
     
  2. Open a DOS box, and run the following: python setup.py py2exe
  3. A directory named ./dist is create by py2exe, and contains all the files that are required to run your script on a bare Windows host. You can remove the ./build directory (temp stuff)
  4. Combine those few files into a single EXE using either your favorite installer, or PE Bundle
  5. More information available on py2exe

An alternative to py2exe is PyInstaller: "PyInstaller is a program that converts (packages) Python programs into stand-alone executables, under Windows, Linux and Irix. [...] PyInstaller is an effort to rescue, maintain and further develop Gordon McMillan's Python Installer (now PyInstaller). Their official website is not longer available and the original package is not longer maintained. Believing that it is still far superior to py2exe, we have setup this site to continue its further development."

First, read the following to understand the issue of compiling and/or distributing Python scripts:

Pyco

Psyco

setuptools

"setuptools () is a collection of enhancements to distutils which let you build .egg files. Once you start using egg files you can include dependencies between package versions and if your product requires a bunch of other packages the installation step will download and install the appropriate versions.

See http://peak.telecommunity.com/DevCenter/EasyInstall for instructions on installing packages built in this way, but in short, the user has to run ez_setup.py from the EasyInstall page, and then a command like:

        easy_install http://example.com/path/to/MyPackage-1.2.3.tgz

would download and install your package and all the other products it depends on. If at a later stage they want to upgrade to a more recent version then all they need to do is to run:

        easy_install --upgrade MyPackage

Installed eggs usually exist in a single file (importable zip) which makes uninstalling especially easy: just one file to delete."

py2exe

py2exe is a Python distutils extension which converts python scripts into executable windows programs, able to run without requiring a python installation.

  1. Install py2exe
  2. Create a script
  3. Run the script including the -w (Windows) option to hide the DOS box that Python opens even when running a GUI application
  4. Distribute the resulting .EXE and its dependent DLLs, or generate an installer

Note that even a no-thrill window developed with the wxPython toolkit with just a tiny menu bar that displays a dialog box, turns into a 300KB EXE, and requires 4 binaries for a total of 2.5Meg (and that's after compressing the four dependencies with UPX).

For information, internally, Python source code is always translated into a "virtual machine code" or "byte code" representation before it is interpreted (by the "Python virtual machine" or "bytecode interpreter").  In order to avoid the overhead of parsing and translating modules that rarely change over and over again, this byte code is written on a file whose name ends in ".pyc" whenever a module is parsed (from a file whose name ends in ".py").

When the corresponding .py file is changed, it is parsed and translated again and the .pyc file is rewritten. There is no performance difference once the .pyc file has been loaded (the bytecode read from the .pyc file is exactly the same as the bytecode created by direct translation).  The only difference is that loading code from a .pyc file is faster than parsing and translating a .py file, so the presence of precompiled .pyc files will generally improve start-up time of Python scripts.

If desired, the Lib/compileall.py module/script can be used to force creation of valid .pyc files for a given set of modules. Note that the main script executed by Python, even if its filename ends in .py, is not compiled to a .pyc file.  It is compiled to bytecode, but the bytecode is not saved to a file.

McMillan Installer

Freeze

If you are looking for a way to translate Python programs in order to distribute them in binary form, without the need to distribute the interpreter and library as well, have a look at the freeze.py script in the Tools/freeze directory [find it in the ActivePython distribution; Guess this refers to the standard Python distro.)

This creates a single binary file incorporating your program, the Python interpreter, and those parts of the Python library that are needed by your program.  Of course, the resulting binary will only run on the same type of platform as that used to create it.

"There is a tool called freeze that is included with Python that does this.  I havn't done it on Windows yet and I have heard that there are some tricks or potential problems with it.  Check the back-postings at dejanews for details.  Basically it scans you code for all imported modules and builds a C module that has all the compiled python modules encoded within it.  Then you compile and linke this file against the Python library and you end up with an executable that along with any binary extension modules you may need will be a distributable version of your program."

cx_Freeze

"The Freeze utility that comes with Python itself requires a source distribution, a C compiler and linker which makes for a complex environment for creating executables. In addition, this method is very slow for creating executables as compared to the other methods. py2exe is intended for development on Windows only and cx_Freeze is intended for cross platform development. Installer uses an import hook which means that the development environment and runtime environment are considerably different."

SQFreeze

Pyrex

PyPy

"The PyPy project aims at producing a simple runtime-system for the Python language. We want to express the basic abstractions within the Python Language itself. We later want to have a minimal core which is not written in Python and doesn't need CPython anymore. We want to take care that technologies such as PSYCO and Stackless will easily integrate."

PyInline

Py2Cmod

Weave

pyPack

SWIG

"SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. SWIG is primarily used with common scripting languages such as Perl, Python, Tcl/Tk, and Ruby, however the list of supported languages also includes non-scripting languages such as Java, OCAML and C#."

distutils

PyScripter

PyChecker

"PyChecker is a tool for finding bugs in python source code. It finds problems that are typically caught by a compiler for less dynamic languages, like C and C++. It is similar to lint."

IDEs

If you prefer to use an IDE instead of a basic text editor, here are the choices I would recommend:

Bigger list here

PyDev

http://pydev.sourceforge.net

PyPe

DrPython

Programmer Studio

ActiveState

Komodo

Visual Python

BlackAdder

The eric3 Python IDE

SPE - Stani's Python Editor

Boa Constructor

FOX

Arachno

PythonWin, a.k.a. PyWin32

WPY

Pmw

Idle

Wing

Writing GUI apps

Some infos

Below is a list of tools to let you build GUI applications. Most are just wrappers around a set of widgets such as Windows' native widgets, wxWidgets, or QT, bringing you back to the days of Windows programming Petzold-style (Mmm...), but some also offer a GUI designer lilke VB, ie. you can draw the windows interface with the mouse. You can read more in the page Gui Programming on the Python site.

Note that the WYSIWYG GUI designer that feels most like VB's is QT Designer, which you can get either directly from QT or by buying the BlackAdder IDE.

Alternatively, you could also use a GUI desiging tool such as the antiquated MS Dialog Editor or its more modern equivalents, just to draw the interface with the mouse and get the coordinates for each widget, and copy/paste this into code. Here are some suggestions I got:

Here are the widgets and/or Python wrappers those GUI designers may require:

Designing the UI as a resource

"Quick side note: depending on your GUI needs, ctypes can be a pretty easy way to go. Create your GUI as resources (e.g. in MS Visual Studio) and wrap them into a tiny DLL. Then use ctypes to load them at runtime and run CreateDialogIndirect. Most of the work involved is simply looking in header files for the values of various Win32 messages and constants, but once you do it the first time you can re-use much of the code over and over."

MFC

PythonWin, a.k.a. PyWin32 is not only an IDE, but also an MFC wrapper so you can build Win32 apps without any extra widgets set. Take a look at the samples under Drive:\Python23\Lib\site-packages\

PythonWin offers the following modules to wrap the Win32 APIs:

Note that Python Win32, a.k.a. Win32all, is part of the ActivePython package, so if you use ActivePython instead of the standard Windows version of Python, Python Win32 is already installed.

More information:

Here's the familiar "Hello, World!" as a dialog box in PyWin32:

from pywin.mfc import dialog, window
import win32con
 
dlgStatic = 130
dlgButton = 128
 
class Mydialog(dialog.Dialog):
    def OnInitDialog(self):
        rc = dialog.Dialog.OnInitDialog(self)
        return rc
 
style = (win32con.DS_MODALFRAME |
    win32con.WS_POPUP |
    win32con.WS_VISIBLE |
    win32con.WS_CAPTION |
    win32con.WS_SYSMENU |
    win32con.DS_SETFONT)
cs = win32con.WS_CHILD | win32con.WS_VISIBLE
s = win32con.WS_TABSTOP | cs
w = 64
h = 64
 
#1. Let's create a dialog box with a label and a pushbutton
dlg = [["PyWin32",(0, 0, w, h), style,  None,   (8, "MS Sans Serif")],]
dlg.append([dlgStatic,"OK",   win32con.IDOK,      (7, h - 18, 50, 14), s | win32con.BS_PUSHBUTTON])
dlg.append([dlgStatic, "Hello, world!", -1, (7, 9, 50, 14), cs | win32con.SS_LEFT])
 
#2. Let's start the dialog
d = Mydialog(dlg)
 
#3. Display it
d.DoModal()

Here's how to add a progress bar, set its range, and increment it:

def OnInitDialog(self):
    rc = dialog.Dialog.OnInitDialog(self)
    self.pbar = win32ui.CreateProgressCtrl()
    self.pbar.CreateWindow (win32con.WS_CHILD | win32con.WS_VISIBLE, (7, 30, 270, 50), self, 1001)
 
#Find out how many *.HTM* in /input, and set range of progress bar
filecount = 0
for file in glob.glob('*.htm*'):
    filecount+=1
self.pbar.SetRange(0,filecount)
                
for file in glob.glob('*.htm*'):
    self.pbar.SetStep(1)
    self.pbar.StepIt()
    [...]

Python GUI API Project

.Net (Mono, DotGNU)

This is very early development, but if you like bleeding edge stuff, you could start looking at how to develop applications using either MS' official .Net framework and its tools (VS.Net and the Python add-on, etc.), or the compatible open-source versions that are Mono and DotGNU. Take a look at IronPython, and boo.

wxPython

More infos here.

PyQT

pyFLTK

PyGTK

"If you like GTK+, you might want to try the glade designer and parse the XML file with libglade and pygtk.  (Generated code is bad). Remember, glade generates XML.  XML is not code, XML is data.  And data is not code.  As long as you stay away from generated code, you will be safe.  Yup, the best of two worlds -- a graphical form designer that stores information in XML data to be parsed by your own python program."

"BTW, there's a python port of glade underway: http://gruppy.sicem.biz/componentes#gazpacho"

FXPy

Binding to the TnFox Toolkit?

http://www.osnews.com/story.php?news_id=9701

PyGUI

WAX

PyUI

Windows

RipSting’s Blender-Python GUI Designer

Blender GUI Wizard

http://www.angelfire.com/nt/teklord/GUIWizard.htm

ActiveState GUI Builder

Venster

PythonWorks Pro

EasyDialogs for Windows

Dabo

DynWin

PythonWin

sdk32 - Partial Python wrap of the Win32 Platform SDK

GTK

MojoView

QT

QT Designer

wxWidgets

Dabo

"Dabo is a 3-tier, cross-platform application development framework, written in Python atop the wxPython GUI toolkit. And while Dabo is designed to create database-centric apps, that is not a requirement. Lots of people are using Dabo for the GUI tools to create apps that have no need to connect to a database at all."

wxDesigner

wxGlade

XRCed

VisualWx

Boa Constructor

See above

PythonCard

Dialogblocks

TCL/TK

Visual TCL

"Visual Tcl is a freely-available, high-quality application development environment for UNIX, Windows, Macintosh and AS400 platforms. Visual Tcl is written entirely in Tcl/Tk and generates pure Tcl/Tk code. This makes porting your Visual Tcl applications either unnecessary or trivial. Visual Tcl is covered by the GNU General Public License."

PAGE - Python Automatic GUI Generator

Resources

Web development

More infos here.

Database access

http://www.python.org/sigs/db-sig/

Networking

Code Snippets

Operators

Watch out when using shortcuts like += on large strings, as they seem to be much slowed than the more lengthy "mystring = mstring + something".

File I/O

Checking if a directory exists

Either...

import os
try:
    os.mkdir("./mydir")
except:
    pass

... or

import os
if not os.path.isdir("./mydir"):
    os.mkdir("./mydir")

Writing to a text file

log = open('test.txt','w')
log.write("Some string")
log.close()

Caution: Under Windows, \r\n turns into 0D0D0A. To get the expected 0D0A, just use \n .

Reading from a text file in one go

f = open("c:/test.txt", "r")
data = f.read()
print data
f.close()

Reading from a text file, line by line

f = open("c:/test.txt", "r")
textlines = f.readlines()
for line in textlines:
    print line
f.close()

Reading for a text file, edit each line, save into new file

import re,sys
 
MAGIC = 10
 
f = open("C:\\input.txt", "r")
textlines = f.readlines()
f.close()
 
#rewrite lines to new file
log = open('output.txt','w')
 
#search for pattern using regex
p = re.compile('^\{(.+?)\}')
for line in textlines:
        m = p.search(line)
        nugget = int(m.group(1))
        nugget += MAGIC
        
        #update line
        start = str(start)
        end = str(end)
        new = "{%s){%s}" % (start,end)
        line = p.sub(new,line)
        #print line
        #adds extra newline :-/
        #print>>log, line
        log.write("%s" % line)
log.close()

Finding if a file is missing from a directory

We'll read a list of files from a text file, and then check if the file exists:

import os.path
 
PATH="C:\\MYDIR\\"
 
f = open(PATH + "files.txt", "r")
textlines = f.readlines()
for line in textlines:
        line = line.strip()
        if not os.path.isfile(PATH + line):
                print "%s NOT FOUND" % line
f.close()

Append stuff to a text file

A first way is to open a file in "a" mode:

f = open("c:/test.txt", "a")
f.write("This is an appended line.\r\n")
f.close()

Another way:

import glob
    
f = open("stuff.to.add.txt", "r")
template = "\n\n" + f.read()
f.close()
 
for frm in glob.glob('*.txt'):
        f = open(frm, "r+")
        content = f.read()
        if 'my pattern' not in content:
                f.seek(0,2)
                f.write(template)
        f.close()

Checking that a file exists

Either...

import os
 
if os.path.exists(file):
    return 1
else:
    return 0

... or

import os
 
def exists(file):
    return os.access(file, os.F_OK)

Checking the size of a file

import os
 
print os.stat(file)[ST_SIZE]

Displaying the last modified date of a file

os.stat() returns the date a file was last modified in epoch, ie. the origin of times being the number of seconds since January 1st 1970. To turn an epoch into eg. YYYY-MM-DD:

filetime = os.stat('myfile.txt')[ST_MTIME]
 
#turns epoch into tuple such as (2004, 8, 13, 2, 35, 2, 4, 226, 0)
filetime = time.gmtime(filetime)
 
#turns tuple into formatted string
print time.strftime("%Y-%m-%d",filetime)

Reading a value from a key in a section of an INI file

import ConfigParser
 
p = ConfigParser.ConfigParser()
p.readfp (open('index.ini'))
try:
    print p.get('files',file)
except:
    print "section 'files' not found"
else:
    print "ok"

Reading all the key/value items in a section in an INI file

import ConfigParser
 
p = ConfigParser.ConfigParser()
p.readfp (open('index.ini'))
for item in p.items('files'):
    print("key = " + item[0] + " value = " + item[1])

Writing data to an INI file

Oddly enough, the ConfigParser doesn't have a write() method, so you need to read the INI file, make the changes in memory, open the file in write mode, and write to it:

def writeini(file,size):
    p = ConfigParser.ConfigParser()
    p.read('index.ini')
    p.set('files', file, size)
 
    fp = open('index.ini','w')
    p.write(fp)
    fp.close()
 
writeini("mykey","myvalue")

Setting the current directory

import os
 
os.chdir('./mydir')

Looping through each file in a directory

import glob
 
for file in glob.glob('*.htm*'):

Note: On the Windows platform, glob() mixes forward- and backslashes, while open() doesn't allow backslashes altogether ("IOError: [Errno 2] No such file or directory: '.\\mydir\myfile.txt' ".)

Reading information from MS Word files

import win32com.client
app = win32com.client.Dispatch('Word.Application')
doc = app.Documents.Add('c:\\stuff.doc')
for rev in doc.Revisions:
    print rev.Author

Using SQLite as file-based database

Several wrappers are available to access SQLite from Python, but two stand out: "pysqlite implements Python's DBAPI and was integrated into Python [2.5]. There is another wrapper, APSW ("Another Python SQLite Wrapper"), which is thinner and closer to SQLite's C API."

Note:

Installing APSW: Just run the EXE that matches your version of Python, eg. apsw-3.3.13-r1.win32-py2.5.exe

Here's how to display information:

import os, sys, time
import apsw
 
print "Using APSW file",apsw.__file__
print "APSW version",apsw.apswversion()
print "SQLite version",apsw.sqlitelibversion()

Here's how to play with SQLite:

if os.path.exists("dbfile"):
        os.remove("dbfile")
 
connection=apsw.Connection("dbfile")
cursor=connection.cursor()

cursor.execute("begin")
cursor.execute("create table foo(x,y,z)")
cursor.execute("insert into foo values(1,2,3)")
cursor.execute("insert into foo values(4, 'five', 6.0)")
cursor.execute("commit")
 
for row in cursor.execute("select * from foo"):
    print row
 
for m,n,o in cursor.execute("select x,y,z from foo"):
    print m,n,o
 
connection.close(True) 

Another example of using APSW (reading a tab-delimited text file to insert books into SQLite)

import re, apsw
 
connection=apsw.Connection("books.sqlite")
cursor=connection.cursor()
 
sql = "CREATE TABLE IF NOT EXISTS books (id INTEGER PRIMARY KEY, isbn VARCHAR, box VARCHAR, title VARCHAR)"
cursor.execute(sql)
 
f = open("books.tsv", "r")
textlines = f.readlines()
f.close()
 
#Extract ISBN + box
p = re.compile('^(.+)\t(\d+)$')
for line in textlines:
        m = p.search(line)
        if m:
                isbn = m.group(1)
                box = m.group(2)
                
                sql = "SELECT COUNT(isbn) FROM books WHERE isbn='%s'" % isbn
                cursor.execute(sql)
                for row in cursor.execute(sql):
                        #Record not found -> Insert
                        if not row[0]:
                                print "No record found for ISBN " + isbn
                                cursor.execute("INSERT INTO books (id,isbn,box) VALUES (NULL,?,?)", (isbn,box))
                                
connection.close(True)

Here's how to perform an INSERT and display the values for each column:

cursor.execute("INSERT INTO person (name, address, tel, web, email)
VALUES (:name, :address, :tel, :web, :email)", locals())

Here's how to safely update/insert data and display the resulting query:

sql = 'UPDATE companies SET name=?,address=?,zip=? WHERE id=?;'
try:
        cursor.execute(sql, (name,address,zip,id) )
except:
        print "Failed UPDATING"
        raise

Using regular expressions

Here's how to loop through a list of web pages, and check whether a given pattern is found therein:

import sys
import urllib
import re
 
for i in range(1,10):
        f = urllib.urlopen("http://www.acme.com/index.asp?page=%s" % i)
        #re.I = ignore case
        if re.search('stringtofind',f.read(), re.I):
                print "Found in %s" % i

Another way to do this:

p = re.compile('stringtofind')
if p.search(f.read()):
    print "Found"
else:
    print "Not found"

Here's how to load a web page, isolate a section, and display it (Note: you cannot call f.read() twice, hence the copying of the page into the 'page' variable):

log = open('found.txt','w')
for i in range(1,10):
        f = urllib.urlopen("http://www.acme.com/index.asp?page=%s" % i)
        print "Checking page %i" % i
        page = f.read()
        if re.search('some text',page, re.I):
                m=re.search('<span class=subject>"(.+?)"</span>',page,re.I)
                if m:
                        log.write("Found in %s\n" % i)
                        log.flush()
log.close()

Here's how to read an HTML file, and display the string between the TITLE tags, in any:

import re
 
f = open('myfile.html', "r")
inputfile = f.read()
f.close()
 
m = re.search('<title>(.*?)</title>',inputfile,re.I)
if m:
    print m.group(1)

... or if you need to extract more than one set of items:

p = re.compile('blabla (.+?) blabla (.+?)')
packed = p.findall(inputfile)
if packed:
    for x in packed:
        print "Item 1 = " + x[0] + " Item 2 = " + x[1]"

If you need to call a regex a great number of times, you can increase performance by compiling the search pattern:

p = re.compile('[0-9]+')
m = p.search('tempo999')
print m.group(0)

To replace an item with another item, use re.sub():

print re.sub('john','jane','john doe')

Note that re.sub() is very much slower than using a string's replace() method:

stuff = stuff.replace('_',' ')

Also, the string with which to replace the pattern to search for must have its backslashes escaped prior to calling re.sub(), using the r prefix to indiquate a raw string (ie. with its backslashes treated as regular characters):

toreplace = r"\\"
body = "#"
print re.sub("#",toreplace,body)

If you wish to tell the re module to treat the replace pattern as is even when it contains backslashes, add a call to its escape() function:

toreplace = re.escape(r"\\")
body = "#"
print re.sub("#",toreplace,body)

Here's how to rewrite a phone number:

#!/usr/bin/python
 
import sys,re
 
#Turn 0123456789 into 01.23.45.67.89
p = re.compile(r'(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)')
phone = p.sub(r'\1.\2.\3.\4.\5',sys.argv[1])
 
print phone

Important: By default, the regex library can't handle even European characters, so you must set a locale, and add the re.LOCALE switch:

locale.setlocale(locale.LC_ALL, 'FR')
mypattern = re.compile("(\d+)\s+(\w+)\s+(\d+)",re.LOCALE)

More infos on using regexes in Python:

Connecting to a web server

Here's how to use urllib to POST to a script:

import urllib
        
url = "http://www.acme.com"
data = {'myfield': somevalue}
urldata = urllib.urlencode(data)
results = urllib.urlopen(url, urldata).read()
print results

Here is an example session that uses the 'GET' method to retrieve a URL containing parameters:

import urllib
params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
print f.read()

The following example uses the 'POST' method instead:

import urllib
params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query ", params)
print f.read()

The following example uses an explicitly specified HTTP proxy, overriding environment settings:

import urllib
proxies = {'http': 'http://proxy.example.com:8080/'}
opener = urllib.FancyURLopener(proxies)
f = opener.open("http://www.python.org")
f.read()

The following example uses no proxies at all, overriding environment settings:

import urllib
opener = urllib.FancyURLopener({})
f = opener.open("http://www.python.org/")
f.read ()

Here's how to use Libcurl to POST to a script:

  1. Install Python and Libcurl (eg. libcurl-7.16.2-win32-ssl-sspi.zip)
  2. Install PyCurl
  3. Use this script:

Here's how to log on to a web server through POST with support for cookies:

urllib vs urllib2 vs httplib

cookielib vs. ClientCookie http://www.voidspace.org.uk/python/articles/cookielib.shtml

Playing with date/time

Here's how to display the current date and time:

import time
import locale
 
#displays '08/20/04 22:05:15'
print time.strftime('%c')
 
#displays 'French_France.1252'
print locale.setlocale(locale.LC_ALL,'')
 
#displays '20/08/2004 22:05:15'
print time.strftime('%c')

The time value as returned by gmtime(), localtime(), and strptime(), and accepted by asctime(), mktime() and strftime(), is a sequence of 9 integers. The return values of gmtime(), localtime(), and strptime() also offer attribute names for individual fields.

Lists

Tuples

Dictionaries

Printing the content of each key:

for i in stuff.keys():
    print i + "=" + stuff[i]

Commenting a block of text

"""
This is one
block of text
"""

ie. three double-quotes in a row.

Exiting a script

import sys
 
sys.exit()

Handling a long line of code

To break a long line of code:

if (somevar) or \
    (someothervar):

Sending an e-mail

Here's how to send an e-mail through code, passing one parameter to the script:

#!/usr/bin/python
 
from email.MIMEText import MIMEText
import smtplib,sys
 
body='''this text will become the body of the message
Using triple-quotes you can span it easily over multiple lines.
the result of an action'''
 
msg = MIMEText(body)
From = "me@acme.com"
To = "you@acme.com"
msg['From'] = From
msg['To'] = To
msg['Subject'] = "Call from " + sys.argv[1]
 
server = smtplib.SMTP("smtp.isp.net")
server.sendmail(From,[To],msg.as_string())
server.quit

Tips from the Python Tutorial

Calling a non-COM DLL from Python

Calling a COM DLL from Python

Shortcut to the last result

In interactive mode, the last printed expression is assigned to the variable _. This means that when you are using Python as a desk calculator, it is somewhat easier to continue calculations, for example:

>>> price * tax
12.5625
>>> price + _
113.0625

Long lines

If a statement or string is too long to fit on a line,use the backslash:

Note that whitespace at the beginning of the line is\
significant."

You can also use """ or ''' :

print """
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
"""

Strings

Unlike a C string, Python strings cannot be changed. Assigning to an indexed position in the string results in an error.

Lists

Unlike strings, which are immutable, it is possible to change individual elements of a list:

a = [’spam’, ’eggs’, 100, 1234]
a[2] = a[2] + 23
a
[’spam’, ’eggs’, 123, 1234]

Variable number of function parameters

When a final formal parameter of the form **name is present, it receives a dictionary containing all keyword argu-ments whose keyword doesn’t correspond to a formal parameter. This may be combined with a formal parameter of the form *name (described in the next subsection) which receives a tuple containing the positional arguments beyond the formal parameter list. (*name must occur before **name.) For example, if we define a function like this:

def cheeseshop(kind, *arguments, **keywords):

Importing modules

There is even a variant to import all names that a module defines:

from fibo import * 

This imports all names except those beginning with an underscore (_).

Modules

The built-in function dir() is used to find out which names a module defines. It returns a sorted list of strings. Without arguments, dir() lists the names [ie. variables and functions] you have defined currently.

page 42

Q&A

UnicodeDecodeError: 'ascii' codec can't decode byte

Python uses Unicode internally, and may need some help when it can't successfully figure out which page code is used to encode a string:

try:
    cursor.execute(sql.decode('utf-8'))
except UnicodeDecodeError:
    try:
        cursor.execute(sql.decode('iso8859-15'))
    except UnicodeDecodeError:
        cursor.execute(sql.decode('cp1252'))

More information:

How to check for errors?

"Pylint analyzes Python source code looking for bugs and signs of poor quality."

How to enhance performance?

Why are strings immutable?

Read that question in a ng. Does it mean a string in Python is read-only?

What's the difference between "import mymodule" and "from mymodule import *"?

The former forces you to prepend the module's name to every membre, eg. mymodule.mymethod(), while the latter imports all the methods into the current namespace, letting you call the methods without the module name. Although easier to use, make sure those new methods don't clash with your current namespace...

Is there a native-code compiler for Windows?

Check out py2exe. Other sources of information are Distributing Python Apps and How can I create a stand-alone binary from a Python script? Also take a look at Psyco.

Py? Pyc? Pyd? Pyo? Pyw?

(From Boudewijn Rempt's book on PyQT): "The translation from Python code to byte-code only happens once: Python saves a compiled version of your code in another file with the extension .pyc, or an optimized compiled version of your code that removes assert statements and line-number tracking in a file with the extension .pyo.

However, that is only done with Python files that are imported from other files: the bootstrap script will be compiled to bytecode every time you run it, but python will create a myapp.pyc from a file myapp.py (which is not shown here)."

IndentationError

"unindent does not match any outer indentation level" : If copy/pasting code from a web page, make sure there are not hidden characters that confuse Python.

Hiding the DOS box when running under Windows?

"Python.exe is used for console mode programs and Pythonw.exe is used for GUI applications that don't need a console window. Python.exe can also be used for GUI programs, but then you get a console window in addition to your GUI window(s)."

How to call a PowerBasic DLL from Python?

http://www.talkaboutprogramming.com/group/alt.lang.powerbasic/messages/7219.html

How to hide the console window when running an EXE generated by py2exe?

From VB to Python

Resources