If you really want to dive into a programming language, the best way is to read its docs. Thus, all notes below are fetched from Python2.6 Doc.
1. Assignment to slices is also possible, and this can even change the size of the list or clear it entirely:

>>> # Replace some items:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # Remove some:
... a[0:2] = []
>>> a
[123, 1234]
>>> # Insert some:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> # Insert (a copy of) itself at the beginning
>>> a[:0] = a
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
>>> # Clear the list: replace all items with an empty list
>>> a[:] = []
>>> a
2. It is not safe to modify the sequence being iterated over in the loop (this can only happen for mutable sequence types, such as lists). If you need to modify the list you are iterating over (for example, to duplicate selected items) you must iterate over a copy. The slice notation makes this particularly convenient:

>>> a = ['cat', 'window', 'defenestrate']
>>> for x in a[:]: # make a slice copy of the entire list
... if len(x) > 6: a.insert(0, x)
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']
3. An example to show the slice of list:

>>> a = [1,2,3]
>>> a[:] = []
>>> a
>>> a = [1,2,3]
>>> b = a
>>> b.append(4)
>>> b
>>> a
>>> c = a[:]
>>> c.append(5)
>>> c
>>> a
4. Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement.

5. A function definition introduces the function name in the current symbol table. The value of the function name has a type that is recognized by the interpreter as a user-defined function. This value can be assigned to another name which can then also be used as a function.

6. The default values are evaluated at the point of function definition in the defining scope, so that:

i = 5

def f(arg=i):
print arg

i = 6
will print 5. The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:

def f(a, L=[]):
return L

print f(1)
print f(2)
print f(3)
This will print:

[1, 2]
[1, 2, 3]
If you don’t want the default to be shared between subsequent calls, you can write the function like this instead:

def f(a, L=None):
if L is None:
L = []
return L
7. When the arguments are already in a list or tuple, it can be unpacked for a function call requiring separate positional arguments.

>>> range(3, 6)
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args)
[3, 4, 5]
8. For Python, PEP 8 has emerged as the style guide that most projects adhere to; it promotes a very readable and eye-pleasing coding style. Every Python developer should read it at some point; I just extract some points here:

  • When possible, put comments on a line of their own.
  • Use docstrings.
  • Name your classes and functions consistently; the convention is to use CamelCase for classes and lower_case_with_underscores for functions and methods.
  • Don’t use fancy encodings if your code is meant to be used in international environments. Plain ASCII works best in any case.
9. list.insert(i, x)
Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).

10. There are three built-in functions that are very useful when used with lists: filter(), map(), and reduce().
filter(function, sequence) returns a sequence consisting of those items from the sequence for which function(item) is true. If sequence is a string or tuple, the result will be of the same type; otherwise, it is always a list. For example, to compute some primes:

>>> def f(x): return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]
map(function, sequence) calls function(item) for each of the sequence’s items and returns a list of the return values. For example, to compute some cubes:

>>> def cube(x): return x*x*x
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
More than one sequence may be passed; the function must then have as many arguments as there are sequences and is called with the corresponding item from each sequence (or None if some sequence is shorter than another). For example:

>>> seq = range(8)
>>> def add(x, y): return x+y
>>> map(add, seq, seq)
[0, 2, 4, 6, 8, 10, 12, 14]
reduce(function, sequence) returns a single value constructed by calling the binary function function on the first two items of the sequence, then on the result and the next item, and so on. For example, to compute the sum of the numbers 1 through 10:

>>> def add(x,y): return x+y
>>> reduce(add, range(1, 11))
11. Consider the following example of a 3x3 matrix held as a list containing three lists, one list per row:

>>> mat = [
... [1, 2, 3],
... [4, 5, 6],
... [7, 8, 9],
... ]
Now, if you wanted to swap rows and columns, you could use a list comprehension:

>>> print [[row[i] for row in mat] for i in [0, 1, 2]]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
In real world, you should prefer builtin functions to complex flow statements. The zip() function would do a great job for this use case:

>>> zip(*mat)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
12. the del statement differs from the pop() method which returns a value. The del statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:

>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
del can also be used to delete entire variables:

>>> del a
Referencing the name a hereafter is an error (at least until another value is assigned to it). We’ll find other uses for del later.

13. Here are some set operations:

>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> a - b # letters in a but not in b
set(['r', 'd', 'b'])
>>> a b # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # letters in both a and b
set(['a', 'c'])
>>> a ^ b # letters in a or b but not both
set(['r', 'd', 'b', 'm', 'z', 'l'])
14. enumerate function will return a list of tuples. The first element in each tuple is the index. For example:

>>> a = [1,2,3,4]
>>> for x in enumerate(a):
... print x
(0, 1)
(1, 2)
(2, 3)
(3, 4)
>>> for x, y in enumerate(a):
... print x, y
0 1
1 2
2 3
3 4
15. To loop over a sequence in reverse, first specify the sequence in a forward direction and then call the reversed() function. To loop over a sequence in sorted order, use the sorted() function which returns a new sorted list while leaving the source unaltered.

16. in Python, unlike C, assignment cannot occur inside expressions. C programmers may grumble about this, but it avoids a common class of problems encountered in C programs: typing = in an expression when == was intended.

from modulename import *
This imports all names except those beginning with an underscore (_).

18. Modules are searched in current directory and the list of directories given by the variable sys.path.

19. A program doesn’t run any faster when it is read from a .pyc or .pyo file than when it is read from a .py file; the only thing that’s faster about .pyc or .pyo files is the speed with which they are loaded.

20. It is possible to have a file called spam.pyc (or spam.pyo when -O is used) without a file spam.py for the same module. This can be used to distribute a library of Python code in a form that is moderately hard to reverse engineer. The module compileall can create .pyc files (or .pyo files when -O is used) for all modules in a directory.

21. The variables sys.ps1 and sys.ps2 define the strings used as primary and secondary prompts:

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print 'Yuck!'
These two variables are only defined if the interpreter is in interactive mode.

22. Without arguments, dir() lists the names you have defined currently:

>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__doc__', '__file__', '__name__', 'a', 'fib', 'fibo', 'sys']
Note that it lists all types of names: variables, modules, functions, etc. dir() does not list the names of built-in functions and variables. If you want a list of those, they are defined in the standard module __builtin__.

23. Note that when using from package import item, the item can be either a submodule (or subpackage) of the package, or some other name defined in the package, like a function, class or variable. The import statement first tests whether the item is defined in the package; if not, it assumes it is a module and attempts to load it. If it fails to find it, an ImportError exception is raised.

24. The import statement uses the following convention: if a package’s __init__.py code defines a list named __all__, it is taken to be the list of module names that should be imported when from package import * is encountered. It is up to the package author to keep this list up-to-date when a new version of the package is released. Package authors may also decide not to support it, if they don’t see a use for importing * from their package.

25. There is another method, zfill(), which pads a numeric string on the left with zeros. It understands about plus and minus signs:

>>> '12'.zfill(5)
>>> '-3.14'.zfill(7)
>>> '3.14159265359'.zfill(5)
26. If the end of the file has been reached, f.read() will return an empty string ("").

>>> f.read()
'This is the entire file.\n'
>>> f.read()
27. f.tell() returns an integer giving the file object’s current position in the file, measured in bytes from the beginning of the file. To change the file object’s position, use f.seek(offset, from_what). The position is computed from adding offset to a reference point; the reference point is selected by the from_what argument. A from_what value of 0 measures from the beginning of the file, 1 uses the current file position, and 2 uses the end of the file as the reference point. from_what can be omitted and defaults to 0, using the beginning of the file as the reference point.

>>> f = open('/tmp/workfile', 'r+')
>>> f.write('0123456789abcdef')
>>> f.seek(5) # Go to the 6th byte in the file
>>> f.read(1)
>>> f.seek(-3, 2) # Go to the 3rd byte before the end
>>> f.read(1)
28. It is good practice to use the with keyword when dealing with file objects. This has the advantage that the file is properly closed after its suite finishes, even if an exception is raised on the way. It is also much shorter than writing equivalent try-finally blocks:

>>> with open('/tmp/workfile', 'r') as f:
... read_data = f.read()
>>> f.closed
29. Python provides a standard module called pickle. This is an amazing module that can take almost any Python object (even some forms of Python code!), and convert it to a string representation; this process is called pickling. Reconstructing the object from the string representation is called unpickling. Between pickling and unpickling, the string representing the object may have been stored in a file or data, or sent over a network connection to some distant machine.
If you have an object x, and a file object f that’s been opened for writing, the simplest way to pickle the object takes only one line of code:

pickle.dump(x, f)
To unpickle the object again, if f is a file object which has been opened for reading:

x = pickle.load(f)
30. A good example to show try-except block:

import sys

f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except IOError as (errno, strerror):
print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
print "Could not convert data to an integer."
print "Unexpected error:", sys.exc_info()[0]
31. In real world applications, the finally clause is useful for releasing external resources (such as files or network connections), regardless of whether the use of the resource was successful.

32. Name spaces are created at different moments and have different lifetimes. The namespace containing the built-in names is created when the Python interpreter starts up, and is never deleted. The global namespace for a module is created when the module definition is read in; normally, module namespaces also last until the interpreter quits. The statements executed by the top-level invocation of the interpreter, either read from a script file or interactively, are considered part of a module called __main__, so they have their own global namespace.(The built-in names actually also live in a module; this is called __builtin__.)

33. In class, Data attributes override method attributes with the same name.

34. Derived classes may override methods of their base classes. Because methods have no special privileges when calling other methods of the same object, a method of a base class that calls another method defined in the same base class may end up calling a method of a derived class that overrides it. (For C++ programmers: all methods in Python are effectively virtual.)

35. Python has two builtin functions that work with inheritance:

  • Use isinstance() to check an object’s type: isinstance(obj, int) will be True only if obj.__class__ is int or some class derived from int.
  • Use issubclass() to check class inheritance: issubclass(bool, int) is True since bool is a subclass of int. However, issubclass(unicode, str) is False since unicode is not a subclass of str (they only share a common ancestor, basestring).

36. Instance method objects have attributes, too: m.im_self is the instance object with the method m(), and m.im_func is the function object corresponding to the method.

37. There are two new valid (semantic) forms for the raise statement:
raise Class, instance

raise instance
In the first form, instance must be an instance of Class or of a class derived from it. The second form is a shorthand for:
raise instance.__class__, instance
38. To add iterator behavior to your classes, define a __iter__() method which returns an object with a next() method. If the class defines next(), then __iter__() can just return self:
class Reverse:
"Iterator for looping over a sequence backwards"
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
def next(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]

>>> for char in Reverse('spam'):
... print char
Generators are a simple and powerful tool for creating iterators. They are written like regular functions but use the yield statement whenever they want to return data. Each time next() is called, the generator resumes where it left-off (it remembers all the data values and which statement was last executed). An example shows that generators can be trivially easy to create:
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]

>>> for char in reverse('golf'):
... print char
The yield statement is only used when defining a generator function, and is only used in the body of the generator function. Using a yield statement in a function definition is sufficient to cause that definition to create a generator function instead of a normal function. When a generator function is called, it returns an iterator known as a generator iterator, or more commonly, a generator. The body of the generator function is executed by calling the generator’s next() method repeatedly until it raises an exception. When a yield statement is executed, the state of the generator is frozen and the value of expression_list is returned to next()'s caller. By "frozen" we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, and the internal evaluation stack: enough information is saved so that the next time next() is invoked, the function can proceed exactly as if the yield statement were just another external call.

39. Be sure to use the import os style instead of from os import *. This will keep os.open() from shadowing the builtin open() function which operates much differently.

40. The glob module provides a function for making file lists from directory wildcard searches:
>>> import glob
>>> glob.glob("C:\\Users\\Yang\\Desktop\\*.py")
['C:\\Users\\Yang\\Desktop\\file_preprocess.py', 'C:\\Users\\Yang\\Desktop\\htmlFunctions.py', 'C:\\Users\\Yang\\Desktop\\proj03.py', 'C:\\Users\\Yang\\Desktop\\template.py', 'C:\\Users\\Yang\\Desktop\\test.py']
41. The most direct way to terminate a script is to use sys.exit().

42. The datetime module supplies classes for manipulating dates and times in both simple and complex ways.
# dates are easily constructed and formatted
>>> from datetime import date
>>> now = date.today()
>>> now
datetime.date(2003, 12, 2)
>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'

# dates support calendar arithmetic
>>> birthday = date(1964, 7, 31)
>>> age = now - birthday
>>> age.days
43. The textwrap module formats paragraphs of text to fit a given screen width:
>>> import textwrap
>>> doc = """The wrap() method is just like fill() except that it returns
... a list of strings instead of one big string with newlines to separate
... the wrapped lines."""
>>> print textwrap.fill(doc, width=40)
The wrap() method is just like fill()
except that it returns a list of strings
instead of one big string with newlines
to separate the wrapped lines.
44. The locale module accesses a database of culture specific data formats. The grouping attribute of locale’s format function provides a direct way of formatting numbers with group separators:
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'English_United States.1252')
'English_United States.1252'
>>> conv = locale.localeconv() # get a mapping of conventions
>>> x = 1234567.8
>>> locale.format("%d", x, grouping=True)
>>> locale.format("%s%.*f", (conv['currency_symbol'],
... conv['frac_digits'], x), grouping=True)
45. The following code shows how the high level threading module can run tasks in background while the main program continues to run:
import threading, zipfile

class AsyncZip(threading.Thread):
def __init__(self, infile, outfile):
self.infile = infile
self.outfile = outfile
def run(self):
f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
print 'Finished background zip of: ', self.infile

background = AsyncZip('mydata.txt', 'myarchive.zip')
print 'The main program continues to run in foreground.'

background.join() # Wait for the background task to finish
print 'Main program waited until background was done.'
While those tools are powerful, minor design errors can result in problems that are difficult to reproduce. So, the preferred approach to task coordination is to concentrate all access to a resource in a single thread and then use the Queue module to feed that thread with requests from other threads. Applications using Queue.Queue objects for inter-thread communication and coordination are easier to design, more readable, and more reliable.

46. The array module provides an array() object that is like a list that stores only homogeneous data and stores it more compactly. The following example shows an array of numbers stored as two byte unsigned binary numbers (typecode "H") rather than the usual 16 bytes per entry for regular lists of python int objects:
>>> from array import array
>>> a = array('H', [4000, 10, 700, 22222])
>>> sum(a)
>>> a[1:3]
array('H', [10, 700])
47. The collections module provides a deque() object that is like a list with faster appends and pops from the left side but slower lookups in the middle. These objects are well suited for implementing queues and breadth first tree searches:
>>> from collections import deque
>>> d = deque(["task1", "task2", "task3"])
>>> d.append("task4")
>>> print "Handling", d.popleft()
Handling task1

unsearched = deque([starting_node])
def breadth_first_search(unsearched):
node = unsearched.popleft()
for m in gen_moves(node):
if is_goal(m):
return m
48. The heapq module provides functions for implementing heaps based on regular lists. The lowest valued entry is always kept at position zero. This is useful for applications which repeatedly access the smallest element but do not want to run a full list sort:
>>> from heapq import heapify, heappop, heappush
>>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
>>> heapify(data) # rearrange the list into heap order
>>> heappush(data, -5) # add a new entry
>>> [heappop(data) for i in range(3)] # fetch the three smallest entries
[-5, 0, 1]
49. Non-identical instances of a class normally compare as non-equal unless the class defines the __eq__() method.

50. int.bit_length() returns the number of bits necessary to represent an integer in binary, excluding the sign and leading zeros:
>>> n = -37
>>> bin(n)
>>> n.bit_length()
51. str.partition(sep)
Split the string at the first occurrence of sep, and return a 3-tuple containing the part before the separator, the separator itself, and the part after the separator. If the separator is not found, return a 3-tuple containing the string itself, followed by two empty strings.


Post a Comment