You are on page 1of 86

Python (IBM):

1. ............... ......... 2
2. ......................................................... ......... 9
3. ........................................................ ....... 17
4. ....... .............................................................. ....... 25
5. ........ ...................................................................... 33
6. ......... ...................................................................... 38
7. ..................... 45
8. .............................................................. 53
9. ............................................................ 60
10. ............................................. 66
11. Web-: Django ..................................... 73
12. (TDD). PyUnit .............. 79

Python: 1.

, JEE , Exigen Services
Exigen Services JEE
. , , B2C , JEE legacy-.
: Python

Python?
Python .
,
: , -. Python
(Guido Van Rossum) 1990- ,
,
, Python
.
,
, Java C++,
. ,
, ,
.
Java C++
; , . Python
,
, , , ,
.
, Python
.
,
.
Python ,
.

, , ,
.
, ,
,
.
Python.
, -
Python.

Python
, ,
. Python ,
, ,
.
, Python , Java
C++. , ,
.

.
Python , , . , Python
, , , Java C++,
.
Python ,
(standalone, -, Web-) .
, Python ,
Python .
Python , ,
. Python
,
, , ,
Web-. Python,
-,
.
Python,
.
, Python
Python, .
, ,
-,
-, Python.

Python
, - :
(runtime environment),
.
, , ,
, ..
Java ,
- Java-. Python
, ,
Python .

Python: CPython,
Jython Python.NET. , C,
Java, .NET.
CPython Python, Python,
.
, C, ,
C. ,
, OC Windows
Linux.
CPython, .
Jython Python Java- (JVM).
JVM, 1.2.2 ( Java 1.6).
Jython Java- ( Java)
Java. Java ,
c JAR- Java-, JavaDOC.
,
CPython, Jython,
, . CPython ,
JVM; , Python
CPython. Jython Java
, JVM.
, GPL,
, .
Python GPL
,
. Python
,
.

Python
Python,
CPython python.
: Python
, Web- www.python.org
, , Linux
Python. Python 2.x
Windows, Python.
Python ,
:

PATH.

, Python,
.
PYTHONHOME. ,
Python. lib,
Python.

PYTHONPATH.

, ,
Python (
).
PYTHONSTARTUP. , Python,
Python.

.
PYTHONHOME\python () [ - | | - ] {}

Python
, ,
. Python,
, .
Python,
.

(_), .
CtrlZ Windows CtrlD Linux.
,
; .
, ,
, . ,
, ,
, .
, ;
.
Python
:
c:\> python- v
c:\> python c import time; print time.asctime()

v Python ,
.
Python ,
, ,
Python.

Python
Python ,
. #.
.
, ,
Python . , Python
5

, , , ,
(;) C++ Java. ,
. ,
{}, .
,
, .
(\),
, ,
\ , , #.
.
, ,
. Python
. ,
.
Python .
,
, Python .
,

@, $, %.
(. ,
).

, Python
, Python,
;
( 1.5J 2j, J -1). Python
, , ,
, Java, immutable-, ..
.
Python bool c True False.
Python , , ,
True False. , ,
True,
False. Python,
bool. ,
Python,
1 (True) 0 (False).


Python :

(tuple);
(list);
(dictionary).
6

.
, .
, . tuple()
.
.
, .
list().
-, -.
,
- -. ,
, .
, ,
/ . dict().
1 , Python.
1. , Python
(w,o,r,l,d)
(2.62,)
[test,'me']
[ ]
{ 5:a, 6:b, 7:c }

#
#
#
#
#





int

Python
Python ,
; , .
, .
Python ; :
def _():
1
2
...

, def, .
:
_()

, Python, . Java,
( ,
, ),
( ).
, ,
, ,
:

#, //
def foo(delimoe, delitel):
return delimoe // delitel
print divide(50,5)
print divide(delitel=5, delimoe=50)

# : 10
# : 10

Python
return, , , return,
None, .
, Python , - ,
return, , return
, ,
return None.
,
, Python - (lambda). lambda ( ),
return, .
, ,
( , ).
Python .
1000 , , ,
.
.
Python ,
,
.

Python, .
, Python
, , ,
Python ( ,
lambda- ..). Python
, Python.

Exigen Services JEE
. , , B2C , JEE legacy-.

Python. 2:

, ,
: Python.
.
,
, .
.
1.
2.
3.
4.
5.
6.
7.

.
(slicing).
.
Unicode.
.
.
.

1.
. Python
, immutable .
:
>>> word = 'strength'
>>> word[2] = 'y'
TypeError: 'str' object does not support item assignment

, , , :
>>> word = word[:3] + '!' + word[4:]
'str!ngth'

:
>>> word = word.replace('!','e')
'strength'

-1:
>>> word[-1]
h

, ,
:
>>> '123'
'123'
>>> "7'8''9"
"7'8''9"

:
>>> s = 'this is first word\
and this is second word'

:
>>> print """
One
Two
Three
"""

escape-.
.
'\n' , '\t' :
>>> s ='a\nb\tc'
>>> print s
a
b
c


:
>>> s = '\001\002\x03'
>>> s
'\x01\x02\x03'
>>> len(s)
3

, ,
, , .

2.
.
. , 0.
, :
>>>
>>>
n
>>>
st
>>>
re

word = 'strength'
word[4]
word[0:2]
word[2:4]

, , ;
:

10

>>> word[:3]
str
>>> word[5:]
gth

:
>>> s = '1234567890'
>>> s[::2]
'13579'
>>> s[1:10:2]
'13579'
>>> s[::-1]
'0987654321'

3.
+ :
>>> var = 'Moscow' + 'city'

, .
* :
>>> '123' * 3
'123123123'

<, <=, ==, !=, >, >=.

4. Unicode
Unicode , .
256 .
u 2 ,
UTF-8:
>>> w = u' '
>>> w
u'\u0412\u0430\u0441\u044f \u041f\u0443\u043f\u043a\u0438\u043d'

: ASCII, UTF-8, UTF-16, KOI8-R,


CP1251, CP866 ..:
>>> s = unicode("", "KOI8-R")
>>> s
u'\u043f\xf7\u044f\u2500\u043f\u2566\u043f\u2561\u043f\u2563\u044f\u250c'

encode() Unicode ,
:
>>> s.encode("KOI8-R")
'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82'

11

5.
.
.
%. ,
:
>>> s = 'Hello %s' % 'word'
>>> s
'Hello word'
>>> s = 'one %s %s' % ('two','three')
>>> s
'one two three'

, %d %f:
>>> s = 'one %d %f' % (2 , 3.5)
>>> s
'one 2 3.500000'

,
.
10 , 5 :
>>> x = 4/3
>>> '%10.5f' % x
'
1.00000'

:
>>> from math import pi
>>> '%015.10f' % pi
'0003.1415926536'

, Template.
:
>>> from string import Template
>>> s = Template('1 $two 3 4 $five')
>>> d={}
>>> d['two']=2
>>> d['five']=5
>>> s.substitute(d)
'1 2 3 4 5'

12

s
r
c
d
i
u
o
x
X
e
E
f
F
g
C
%

, repr, str

, d (no longer unsigned)


Floating-point exponent,
, e,
Floating-point decimal
Floating-point decimal
Floating-point e
Floating-point E

f
F

6.
. :
find
>>>
>>>
4
>>>
16
>>>
-1
join

, -1:
s = 'The find method finds a substring'
s.find('find')
s.find('finds')
s.find('findsa')

>>> seq = ['one','two','three']


>>> sep = ','
>>> sep.join(seq)
'one,two,three'
split

join, :

>>> s = '/usr/local/bin'
>>> s.split('/')
['', 'usr', 'local', 'bin']
replace

>>> s = 'replace method returns a string'


>>> s.replace('returns','return')
'replace method return a string'

13

strip

>>> '
this is whitespace string
'this is whitespace string'

'.strip()

replace, .
'1' '3', '2' '4'
:
translate

>>> from string import maketrans


>>> table = maketrans('12', '34')
>>> '1212 5656'.translate(table)
'3434 5656'

str, int, ord, chr:

str
int
ord
chr

;
;
;
.

, Python 3.0
S.capitalize()
S.ljust(width [, fill])
S.center(width [, fill])
S.lower()
S.count(sub [, start [, end]])
S.lstrip([chars])
S.encode([encoding [,errors]])
S.maketrans(x[, y[, z]])
S.endswith(suffix [, start [, end]])
S.partition(sep)
S.expandtabs([tabsize])
S.replace(old, new [, count])
S.find(sub [, start [, end]])
S.rfind(sub [,start [,end]])
S.format(fmtstr, *args, **kwargs)
S.rindex(sub [, start [, end]])
S.index(sub [, start [, end]])
S.rjust(width [, fill])
S.isalnum()
S.rpartition(sep)
S.isalpha()
S.rsplit([sep[, maxsplit]])
S.isdecimal()
S.rstrip([chars])
S.isdigit()
S.split([sep [,maxsplit]])
S.isidentifier()
S.splitlines([keepends])
S.islower()
S.startswith(prefix [, start [, end]])
S.isnumeric()
S.strip([chars])
S.isprintable()
S.swapcase()
S.isspace()
S.title()
S.istitle()
S.translate(map)
S.isupper()
S.upper()
S.join(iterable)
S.zfill(width)

14

7.
. ,
, :
, .
:
0 .
1- . array.
, array.tostring().
.
2- . , , array
, .
3- . cStringIO, -,
. getvalue().
4- . ,
. , append().
, .

15

:
import time
loop_count = 1000000
def method1():
from array import array
char_array = array('c')
for num in xrange(loop_count):
char_array.fromstring(`num`)
return char_array.tostring()
def method2():
str_list = []
for num in xrange(loop_count):
str_list.append(`num`)
return ''.join(str_list)
def method3():
from cStringIO import StringIO
file_str = StringIO()
for num in xrange(loop_count):
file_str.write(`num`)
return file_str.getvalue()
def method4():
return ''.join([`num` for num in xrange(loop_count)])
t1 = time.time()
method1()
t2 = time.time()
print "\t%.1f" %
method2()
t3 = time.time()
print "\t%.1f" %
method3()
t4 = time.time()
print "\t%.1f" %
method4()
t5 = time.time()
print "\t%.1f" %

((t2 - t1))
((t3 - t2))
((t4 - t3))
((t5 - t4))


. ,
, ,
,
- . , , .
. ,
Python. 2.6.

16

Python. 3:

, ,
: , Python
. ,
.

. Java C
. , Java Vector,
.
Perl. , ,
.
.
1.
2.
3.
4.
5.
6.
7.

.
.
.
.
(Tuple).
(Set).
filter(), map(), zip(), reduce().

1.
list,
, ,
. , ..
. ()
. (performance)
.
1. .
2. .
3. , , ..
, .
4. , 3.
5. , , O(n).
6. , , .
.
:
>>> lst = ['spam', 'drums', 100, 1234]

, .
, :
>>> lst[1:3]
['drums', 100]

17

, :
>>>
>>>
>>>
[1,

lst[3] = 'piano'
lst[0:2] = [1,2]
lst
2, 100, 'piano']

:
>>> lst[1:1] = ['guitar','microphone']
>>> lst
[1, 'guitar', 'microphone', 2, 100, 'piano']

:
>>> numbers = [1,2,3,4,5,6,7,8,9,0]
>>> numbers[::4]
[1, 5, 9]

2.
:

;
;
;
(list comprehension);
sequence unpacking.

.
1. L1 = L2[:] . .
2. L1 = list(L2) .
3. L1 = L2 , . 3- ,
, .
:
L1 + L2

, :
L1 * 2

:
for x in L:

:
for x in sorted(L):

18

:
for x in set(L):

:
for x in reversed(L):

, 1- , 2-
:
for item in set(L).difference(L2)

, , list
comprehension 10
:
>>> a = [ i*i for i in range(1,10)]
>>> a
[1, 4, 9, 16, 25, 36, 49, 64, 81]

:
>>> a = [ i*i for i in range(1,10) if i % 2 == 0]
>>> a
[4, 16, 36, 64]


:
words = ' to perform the task of sorting the words in a string by their length'.split()
wordlens = [(len(word), word) for word in words]
wordlens.sort()
print ' '.join(w for (_, w) in wordlens)
>>> a by in of to the the task their words length string perform sorting

Sequence unpacking :
a, b = [1,2]

3.
:

append , extend ;
insert ;
index
count ;
remove , del ;
sort ;
reverse ;
pop ;
len ;
max ;
min ;

19

in .

, .
append():
>>>
>>>
>>>
>>>
[1,

lst = [1, 'guitar', 'microphone', 2, 100, 'piano']


lst2 = ['sintezator','drums']
lst.append(lst2)
lst
'guitar', 'microphone', 2, 100, 'piano', ['sintezator', 'drums']]

insert:
>>> lst.insert(0,'vocal')
>>> lst
['vocal', 1, 'guitar', 'microphone', 2, 100, 'piano', ['sintezator', 'drums']]

, , in:
>>> 2 in lst
True
>>> 10 in lst
False
index()

>>> lst.index('guitar')
2
count()

- :

>>> lst.count('vocal')
1
remove()

>>> lst.remove(100)
>>> lst
['vocal', 1, 'guitar', 'microphone', 2, 'piano', ['sintezator', 'drums']]
del

del lst[1]

,
.
sort()

>>> lst.sort()
>>> lst
[1, 2, ['sintezator', 'drums'], 'guitar', 'microphone', 'piano', 'vocal']
reverse()

>>> lst.reverse()
>>> lst

20

['vocal', 'piano', 'microphone', 'guitar', ['sintezator', 'drums'], 2, 1]

,
, :
pop()

>>> lst.pop()
>>> lst
['vocal', 'piano', 'microphone', 'guitar', ['sintezator', 'drums'], 2]
len()

>>> len(lst)
6
max()

>>> max(lst)
'vocal'
min()

>>> min(lst)
2
extend()

append(), :

>>> lst.extend([3,4])
>>> lst
['vocal', 'piano', 'microphone', 'guitar', ['sintezator', 'drums'], 2, 3, 4]

4.

(LIFO, last-in, first-out). pop():
>>>
>>>
>>>
>>>
>>>
[1,

stack = [1,2,3,4,5]
stack.append(6)
stack.append(7)
stack.pop()
stack
2, 3, 4, 5, 6]

,
(FIFO, first-in, first-out). pop()
0:
>>> queue = ['rock','in','roll']
>>> queue.append('alive')
>>> queue.pop(0)
>>> queue
['in', 'roll', 'alive']

21

5. (Tuple)
(immutable), ,
(tuple). , .
( ). ,
, , :
>>> t = 1,[2,3]
>>> t
(1, [2, 3])
>>> t[1] = 2
TypeError: 'tuple' object does not support item assignment
>>> t[1].append(4)
>>> t
(1, [2, 3, 4])

tuple() :
>>> tuple('abc')
('a', 'b', 'c')

6. (Set)
. ,
.. .
:
>>> s = set('abcde')
>>> s
set(['a', 'c', 'b', 'e', 'd'])
>>> s2 = set('aghij')
>>> s2
set(['a', 'h', 'j', 'g', 'f'])

, :

>>> s3 = s - s2
>>> s3
set(['c', 'b', 'e', 'd'])

>>> s3 = s | s2
>>> s3
set(['a', 'c', 'b', 'e', 'd', 'g', 'i', 'h', 'j'])

>>> s3 = s & s2
>>> s3
set(['a'])

22

:
add() :
>>> s.add(6)
>>> s
set(['a', 'c', 'b', 'e', 'd', 6])

remove() :
>>> s.remove('a')
>>> s
set(['c', 'b', 'e', 'd', 6])

:
>>> for item in s:print (item)
c
b
e
d
6

.
, :
>>> L = [1,2,3,4,1,2,6,7]
>>> set(L)
set([1, 2, 3, 4, 6, 7])
>>> L = list(set(L))
>>> L
[1, 2, 3, 4, 6, 7]

:
, :
>>> programmers = set(['ivanov','petrov','sidorov'])
>>> managers = set(['ivanov','moxov','goroxov'])

, , :
>>> programmers & managers
set(['ivanov'])

:
>>> programmers | managers
set(['ivanov', 'petrov', 'sidorov', 'goroxov', 'moxov'])

, :
>>> programmers - managers
set(['petrov', 'sidorov'])

23

7. filter(), map(), zip(), reduce().


,
sequence, function(item) .
. : 100:
filter(function, sequence)

def f(x):
for y in xrange(2, x):
if x%y==0: return 0
return 1
print filter(f, xrange(2, 100))
>>> [2, 3, 5, 7, 11, 13, 17, 19, 23, ... , 59, 61, 67, 71, 73, 79, 83, 89, 97]

, function
. ,
1 10:
map(function, sequence)

def cube(x): return x*x*x


print map(cube, xrange(1, 11))

:
seq1 = [1,2,3]
seq2 = [11,12,13]
for x, y in map(None, seq1, seq2):
print x, y
>>> 1 11
>>> 2 12
>>> 3 13

, map() ,
, :
zip(sequence)

>>> a = (1, 2, 3, 4)
>>> b = (5, 6, 7, 8)
>>> zip(a, b)
[(1, 5), (2, 6), (3, 7), (4, 8)]

,
function
sequence, . . ,
:
reduce(function, sequence)

>>> def add(x, y): return x+y


...
>>> reduce(add, xrange(1, 11))
55


, Python .
,
.
. , , ,
.
.

24

2.6.

25

Python: 4.

, ,
: ,
. , , (mutable) ,
.
.
, . :
1. , . ,
.
2. , ,
, .
3. , .
(heterogeneous).
immutable , , , float ,
.
4. - .
5. , , , .
.
1.
2.
3.
4.

.
/ .
.
.

1.
(dictionary) .
: . {}
. , ,
, , .
.
key: value del.
keys() ;
sort().
has_key(), 3.0 in.
:
, .

26

:
>>> dic = {'vanya' : 23323223, 'smith' : 32232332}
>>> dic['fedya'] = 33332222
>>> dic
{'vanya': 23323223, 'fedya': 33332222, 'smith': 32232332}
>>> dic['smith']
32232332
>>> del dic['vanya']
>>> dic
{'fedya': 33332222, 'smith': 32232332}
>>> dic.keys()
['fedya', 'smith']
>>> dic.has_key('fedya')
True

:
1. , :
D = {'name': 'mel', 'age': 45}

2. :
D = {}
D['name'] = 'mel'
D['age'] = 45

3. dict() .
.
:
d1
d2
d3
d4

=
=
=
=

dict(id=1948, name="Washer", size=3)


dict({"id": 1948, "name": "Washer", "size": 3})
dict([("id", 1948), ("name", "Washer"), ("size", 3)])
dict(zip(("id", "name", "size"), (1948, "Washer", 3)))

4. fromkeys() :
D = {}.fromkeys(['name', 'age'],123)

5. :
d = dict((x, x**2) for x in xrange(5))

27

2. /
dict()
len()

clear()
copy()

deepcopy()

fromkeys()

get()

has_key()
items()

iteriyems()
keys()

iterkeys()
pop()

popitem()

update()

values()

itervalues()
in

, ;

del

, ;

dict()

, :
>>> items = [('name','sveta'),('age',20)]
>>> d = dict(items)
>>> d
{'age': 20, 'name': 'sveta'}
>>> len(d)
2
in()

: .
28

:
people = {'Alice': {'phone': '2341', 'addr': 'Foo drive 23' },
'Beth': {'phone': '9102', 'addr': 'Bar street 42'}}
name = 'Alice'
key = 'phone'
if name in people:
print "%s phone is %s" % (name, people[name][key])
>>> Alice phone is 2341
copy()

:
>>> x = {"user":'admin','attr':[1,2,3]}
>>> y = x.copy()
>>> y
{'user': 'admin', 'attr': [1, 2, 3]}

copy() : , , :
>>> x['attr'].remove(1)

, .
, deepcopy().
>>> from copy import deepcopy
>>> y = x.deepcopy()
fromkeys()

>>> {}.fromkeys(['name', 'age'])


{'age': None, 'name': None}

:
>>> {}.fromkeys(['name', 'age'],123)
{'age': 123, 'name': 123}
get()

, None:

>>> d = {}
>>> print d.get('name')
None
has_key()

, :

>>> d = {}
>>> d.has_key('name')
False
items()

for key, value in d.items():


print(key, value)

29

iteriyems()

>>> for k, v in d.iteritems():


...
print k, v
keys()

iterkeys()

>>> d.keys()
['url', 'title']
>>> d.iterkeys()
<dictionary-keyiterator object at 0xb7c4dd00>
pop()

>>> d.pop('title')
>>> d
{'url': 'http://www.python.org'}
popitem()

>>> d = {'title': 'Python Web Site', 'url': 'http://www.python.org', 'www': 'python'}


>>> d.popitem()
>>> d
{'www': 'python', 'title': 'Python Web Site'}
update()

>>> d2 = {'www':'python.org'}
>>> d.update(d2)
>>> d
{'www': 'python.org', 'title': 'Python Web Site'}
values()
>>>
>>>
>>>
>>>
>>>
{1:
>>>
[1,
del

d={}
d[1]=1
d[2]=2
d[3]=3
d
1, 2: 2, 3: 3}
d.values()
2, 3]

: :

>>> del d[2]


>>> d
{1: 1, 3: 3}

3.
(map), ,
.

30

:
<, <=, ==, !=, >=, >

, for:
>>>
...
...
>>>
...
..
>>>
>>>
>>>

table = {'Python': 'Guido van Rossum',


'Perl':
'Larry Wall',
'Tcl':
'John Ousterhout' }
for lang in table:
print(lang, table[lang])
Tcl
Python
Perl

John Ousterhout
Guido van Rossum
Larry Wall

:
>>> Matrix = {}
>>> Matrix[(2, 3, 4)] = 88
>>> Matrix[(7, 8, 9)] = 99
>>>
>>> X = 2; Y = 3; Z = 4
>>> Matrix[(X, Y, Z)]
88
>>> Matrix
{(2, 3, 4): 88, (7, 8, 9): 99}

:
>>> man = {'name': 'Serg',
...
'jobs': ['programmer', 'writer'],
...
'web': 'www.iakovlev.org',
...
'home': {'city': 'Moscow', 'zip':129000}}
>>> man['name']
Serg
>>> man['jobs'][1]
'writer'

4.
1. , :
def histogram(s):
d = dict()
for c in s:
if c not in d:d[c] = 1
else:d[c] += 1
return d
hist = histogram('how many times')
>>> {'a': 1,'e': 1,'i': 1,'h': 1,'m': 2,'o': 1,'n': 1,'s': 1,'t': 1,'w': 1,'y': 1}

31

:
def invert_dict(d):
inv = dict()
for key in d:
val = d[key]
if val not in inv:inv[val] = [key]
else:inv[val].append(key)
return inv
print invert_dict(hist)
>>> {1: ['a', 'e', 'i', 'h', 'o', 'n', 's', 't', 'w', 'y'], 2: [' ', 'm']}

2. :
import string
import sys
words = {}
strip = string.whitespace + string.punctuation + string.digits + "\"'"
filename = 'file'
for line in open(filename):
for word in line.lower().split():
word = word.strip(strip)
if len(word) > 2:
words[word] = words.get(word, 0) + 1
for word in sorted(words):
print("'{0}' occurs {1} times".format(word, words[word]))

3. :
author = {"php":"Rasmus Lerdorf",\
"perl":"Larry Wall",\
"tcl":"John Ousterhout",\
"awk":"Brian Kernighan",\
"java":"James Gosling",\
"parrot":"Simon Cozens",\
"python":"Guido van Rossum"}
# :
langs = author.keys()
langs.sort()
for language in langs:
print language," - ",author[language]
# :
for key in sorted(author.iterkeys()):
print "%s: %s" % (key, author[key])
>>>
>>>
>>>
>>>
>>>
>>>
>>>

awk java parrot


perl php python
tcl -

Brian Kernighan
James Gosling
- Simon Cozens
Larry Wall
Rasmus Lerdorf
- Guido van Rossum
John Ousterhout

32

4. , .. :
def invert_dict_nonunique(d):
newdict = {}
for k, v in d.iteritems():
newdict.setdefault(v, []).append(k)
return newdict
d = {'child1': 'parent1','child2': 'parent1','child3': 'parent2','child4': 'parent2'}
print invert_dict_nonunique(d)
>>> {'parent2': ['child3', 'child4'], 'parent1': ['child1', 'child2']}

: ,
. , , (mutable)
, .
.

.
2.6.

33

Python: 5.
, ,
:
. .

, .
,
.
:

: .
: ,
, .
,
.
: ,
, , .

C .
1.
2.
3.
4.
5.

.
.
.
.
.

1.
Python ,
. .
.
.py. my_module.py
, , PYTHONPATH,
, '.pth',
. PYTHONPATH
'.pth', . , ,
sys.path.
, , ,
-. .
. .
, namespace,
, , .

34

2.
, (, my_module.py),
:
>>> python

:
>>> import my_module

, :
>>> my_module.func1()
>>> my_module.func2()
...

:
>>> f1 = my_module.func1

:
>>> from my_module import func1, func2
>>> func1()

, :
>>> from my_module import *
>>> func1()

:
>>> from my_module import open as my_open

. from ,
read-only:
>>> from small import x, y
>>> x = 42

x , x, y
small :
>>> import small
>>> small.x = 42

x .
import from ,
.
,
reload().

35

,
.
, :
___.___ .
. import
.

3.
, ,
my_module.pyc , my_module.py, ,
- my_module. , ,
my_module.py my_module.pyc.
- - (
),
.
:
1. -O
- '.pyo'. ,
, '.pyc'- .
2. -OO , , .
3. , , .
.
4. '.py' '.pyo',
'.py'. ,
.
5. , ,
'.so' '.dll' Windows.
6. '.zip' .
7. Java-, Jython.

4.
Python . 200
, - , :
, , , + , GUI ..
http://docs.python.org/library/.
, ;
,
, sys.
sys.path ,
. PYTHONPATH
. :

36

>>> import sys


>>> sys.path.append(/home/my/lib/python)

, , dir().
:
>>> dir(sys)
['__displayhook__', '__doc__', '__egginsert', '__excepthook__', '__name__',
...
'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info']

5.
.
.
.
, , PYTHONPATH .
,
,
.
, , TCP. Server
Client:
TCP/
_init_.py
main.py
Server/
_init_.py
tcp.py
server.py
lib.py
Client/
_init_.py
tcp.py
client.py
lib.py

_init_.py , , .
. :
>>> import TCP.Server.lib
>>> import TCP.Client.lib

:
>>> import TCP.Server.lib.connect()

:
>>>
>>>
>>>
>>>

from TCP.Server import lib as server_lib


from TCP.Client import lib as client_lib
server_lib.connect()
client_lib.connect()

37

lib , , TCP.Server ..
, .
:
>>> from TCP import *

__init__.py __all__ , ,
. :
__all__ = ["Server", "Client"]

.
.

.
.
, .
, .
, .
,
.
Python. 2.6.

38

Python: 6.
, ,
: , , .
, .
. .
, . ,
self. ,
, .
-
() Python. ,
.
.
1. :
.
. count(),
: 'abc'.count('a') [1, 2,
'a'].count('a'). .
2. :
. .
.
,
state.
3. : .
.
4. : .
-
.
1. , ,
.
2. .
3. .
4. .
. .
:
i.
ii.

use cases ,
;
.

- , ,
.
Python C++ Modula-3.

39

:
a.
b.
c.
d.

;
;
;
public, .. ;
, .. .

- .
1.
2.
3.
4.
5.

.
.
self.
.
: .

1.
.
:
class _:
1
.

. C++ ,
, .
, :
_ = _()

.
, . ,
.
, , .
-, .
:

;
.

2.
:

;
-.

40

.
, .
def.
obj.attrname.
.
class Simple:
u' '
var = 87
def f(x):
return 'Hello world'

Simple.var Simple.f . :
>>> print Simple.__doc__


>>> print Simple.var.__doc__
int(x[, base]) -> integer
...

, :
smpl = Simple()

smpl. , -
, , :
class Simple:
def __init__(self):
self.list = []

smpl list.
:
class Simple:
def __init__(self, count, str):
self.list = []
self.count = count
self.str = str
>>> s = Simple(1,'22')
>>> s.count, s.str
1 22

(private) ..
:

41

class Simple:
u' '
__private_attr = 10
def __init__(self, count, str):
self.__private_attr = 20
print self.__private_attr
s = Simple(1,'22')
print s.__private_attr

__private_attr
.
:
def method_for_simple(self, x, y):
return x + y
class Simple:
f = method_for_simple
>>> s = Simple()
>>> print s.f(1,2)
3

:
class Customer:
pass
custom = Customer()
custom.name = ''
custom.salary = 100000

3. self
self. ,
: self .
self , :
class Simple:
def __init__(self):
self.list = []
def f1(self):
self.list.append(123)
def f2(self):
self.f1()
>>> s = Simple()
>>> s.f2()
>>> print s.list
[123]

Self "this" C++.

42

4.
:
class Derived(Base):

:
class Derived(module_name.Base):

: ,
, .
.
:
Base.method()

:
class Derived(Base1,Base2,Base3):

:
1.
2.
3.
4.

Derived;
Base1, Base1;
Base2, Base2
..

5.
: Person , , ;
Manager . Person
str,
.
, __str__.
# -*- coding: utf-8 -*class Person:
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def lastName(self):
return self.name.split()[-1]
def giveRaise(self, percent):
self.pay = int(self.pay * (1 + percent))
def __str__(self):
return '[Person: %s, %s]' % (self.name, self.pay)
class Manager(Person):
def __init__(self, name, pay):
Person.__init__(self, name, 'mgr', pay)
def giveRaise(self, percent, bonus=100):
Person.giveRaise(self, percent + bonus)

43

Person:
>>> ivan = Person(' Petrov')

Person:
>>> john = Person('John Sidorov', job='dev', pay=100000)

__str__;
>>> print(ivan)
>>> print(john)

:
>>> print(ivan.lastName(), john.lastName())

:
>>> john.giveRaise(.10)

:
>>> print(john)

Manager:
>>> tom = Manager('Tom Jones', 50000)

:
>>> tom.giveRaise(.10)

:
print(tom.lastName())
print(tom)

:
[Person: Petrov, 0]
[Person: John Sidorov, 100000]
('Petrov', 'Sidorov')
[Person: John Sidorov, 110000]
Jones
[Person: Tom Jones, 5055000]

44


, , .
, .
. .
, . ,
self. ,
, .
() . ,
, .
. .
. , ,
, ' '.
.
2.6.

45

Python. 7:

, ,

; open-source
www.iakovlev.org. .
: ,
-
.
Python.
. ,
, , , , ..
.
1. .
2. .
3. .
4. .
5. Bound unbound .
6. super.
7. .
8. .
9. Property.
10. Singleton.
11. .
12. .
13. .
14. Sequence.

1.
- . -
:
__name__

__module__
__dict__

, ;

__bases__
__doc__

46

2.
() -.
, ( ) . :
__dict__

, ;

__class__

-, ;

. ,
;
__init__

. ,
;
__del__

__cmp__

__hash__

- , 32- ;

__getattr__

, ;

__setattr__

__delattr__

__call__

3.
.
:
__len__

__getitem__

__setitem__

__delitem__

__getslice__

__setslice__

__delslice__

__contains__

in.

47

4.
.
__repr__
__str__

__oct__ , __hex__ , __complex__ , __int__ , __long__ , __float__

5. Bound unbound
. Cat, Barsik:
class Cat:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print 'I am hangry...'
self.hungry = False
else:
print 'No, thanks!'
class Barsik(Cat):
def __init__(self):
self.sound = 'Aaaammm!'
print self.sound

:
>>> brs = Barsik()
Aaaammm!
>>> brs.eat()
AttributeError: Barsik instance has no attribute 'hungry'

, hungry .
, ,
, . .
:
class Barsik(Cat):
def __init__(self):
Cat.__init__(self)
self.sound = 'Aaaammm!'
print self.sound

, Cat
unbound-, ,
bound-. bound-
.

48

6. super
: , ,
new-style.
super :
__metaclass__ = type
...
class Barsik(Cat):
def __init__(self):
super(Barsik, self).__init__()
self.sound = 'Aaaammm!'
print self.sound
>>> brs = Barsik()
>>> brs.eat()
Aaaammm!
I am hangry...

7.
, self:
class Spam:
numInstances = 0
def __init__(self):
Spam.numInstances = Spam.numInstances + 1
def printNumInstances( ):
print "Number of instances created: ", Spam.numInstances
>>> a=Spam()
>>> b=Spam()
>>> printNumInstances()
Number of instances created:


staticmethod, , :
class Multi:
def imeth(self, x):
print self, x
def smeth(x):
print x
def cmeth(cls, x):
print cls, x
smeth = staticmethod(smeth)
cmeth = classmethod(cmeth)
>>> Multi.smeth(3)
3
>>> obj=Multi()
>>> obj.smeth(5)
5

classmethod
(cls):

49

>>> Multi.cmeth(7)
__main__.Multi 7
>>> obj.cmeth(10)
__main__.Multi 10

8.
, , ,
.
__iter__ next. __iter__ next:
class Reverse:
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('12345'):
>>>
print char
5
4
3
2
1

:
>>> rvr = list(Reverse('12345'))
>>> rvr
['5', '4', '3', '2', '1']

9. Property
Property , property,
:
class DateOffset:
def __init__(self):
self.start = 0
def _get_offset(self):
self.start += 5
return self.start
offset = property(_get_offset)
>>> d = DateOffset()
>>> d.offset
5
>>> d.offset
10

50

10. Singleton
. __new__:
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
return cls._instance
>>> one = Singleton()
>>> two = Singleton()
>>> id(one)
3082687532
>>> id(two)
3082687532

11.
, __slots__.
, :
class limiter(object):
__slots__ = ['age', 'name', 'job']
>>> x=limiter()
>>> x.age = 20

12.
, __call__ .
. Person, - people,
. Sortkey:
class SortKey:
def __init__(self, *attribute_names):
self.attribute_names = attribute_names
def __call__(self, instance):
values = []
for attribute_name in self.attribute_names:
values.append(getattr(instance, attribute_name))
return values
class Person:
def __init__(self, forename, surname, email):
self.forename = forename
self.surname = surname
self.email = email

51

>>> people=[]
>>> p=Person('Petrov','','')
>>> people.append(p)
>>> p=Person('Sidorov','','')
>>> people.append(p)
>>> p=Person(u'Ivanov','','')
>>> people.append(p)
>>> for p in people:
...
print p.forename
Petrov
Sidorov
Ivanov
>>> people.sort(key=SortKey("forename"))
>>> for p in people:
...
print p.forename
Ivanov
Petrov
Sidorov

13.
, .
, __get__ , __set__ ,
__delete__, .
:
class ExternalStorage:
__slots__ = ("attribute_name",)
__storage = {}
def __init__(self, attribute_name):
self.attribute_name = attribute_name
def __set__(self, instance, value):
self.__storage[id(instance), self.attribute_name] = value
def __get__(self, instance, owner=None):
if instance is None:
return self
return self.__storage[id(instance), self.attribute_name]
class Point:
__slots__ = ()
x = ExternalStorage("x")
y = ExternalStorage("y")
def __init__(self, x=0, y=0):
self.x = x
self.y = y
>>> p1=Point(1,2)
>>> p2=Point(3,4)

Point x, y, ,
ExternalStorage.

52

14. Sequence
__getitem__, __setitem__.
MySequence ,
: 1 3 5 7 ...
__del__ , __len__:
class MySequence:
def __init__(self, start=0, step=1):
self.start = start
self.step = step
self.changed = {}
def __getitem__(self, key):
return self.start + key*self.step
def __setitem__(self, key, value):
self.changed[key] = value
>>>
>>>
1
>>>
3
>>>
201

s = MySequence(1,2)
s[0]
s[1]
s[100]

, ,
-
.
, -
. .
, , .
.
, .
.
Python.
2.6.


; open-source
www.iakovlev.org. .

53

Python: 8.

, ,

; open-source
www.iakovlev.org. .
: .
Python .
, , ,
.
.
1. .
2. .
3. /.
4. .
5. .
6. .
7. .
8. Pickling.
9. struct.
10. .

1.
open:
open(name[, mode[, buffering]])

. .
, . (mode) open:
'r' .
'w' .
'a' .
'b' .
'+' /.
'+' .
. 'rb'.
. ,
/ .
.

54

2.
: sys.stdin,
sys.stdout, , urllib.urlopen ..
:
>>>
>>>
>>>
>>>

f = open('my_file', 'w')
f.write('Hello, ')
f.write('World!')
f.close()

:
>>> f = open('my_file', 'r')
>>> f.read(5)
'Hello'
>>> f.read()
', World!'

3. /
,
(pipe):
cat my_file | python test.py

cat my_file sys.stdout


. , sys.stdin ,
:
test.py:
import sys
text = sys.stdin.read()
words = text.split()
wordcount = len(words)
print 'Wordcount:', wordcount

(pipe) ,
.

4.
read() , .
seek:
seek(offset[, whence])

offset ;
whence , ,
.

55

:
>>> f = open(r'my_file', 'w')
>>> f.write('01234567890123456789')
>>> f.seek(5)
>>> f.write('Hello, World!')
>>> f.close()
>>> f = open(r'my_file')
>>> f.read()
'01234Hello, World!89'

tell() .

5.
. :
file.readline()

readline() ,
, .
:
file.readlines()

:
file.writelines()

. :
f = open(r'my_file')
lines = f.readlines()
f.close()
lines[0] = "This is a my_file2 \n" # 1-
f = open(r'my_file2','w')
f.writelines(lines)
f.close()

6.
close(). ,
, .
1. ,
.
2. .
3. ,
. ,
, .

56

try/finally:
try:
#
finally:
file.close()

, :
with open("my_file") as somefile:
do_something(somefile)

,
/ flush(),
. .

7.
.
read() :
f = open(filename)
while True:
char = f.read(1)
if not char: break
process(char)
f.close()

readline():
f = open(filename)
while True:
line = f.readline()
if not line: break
process(line)
f.close()

:
for line in open(filename):
process(line)

8. Pickling
,
. pickle:
import pickle
t1 = [1, 2, 3]
s = pickle.dumps(t1)
t2 = pickle.loads(s)
print t2
[1, 2, 3]

57

: t1 t2 , .

9.
struct C
. .
.
:
pack(format, value1, value2 ...)

, value1 ..., .
,
format.
unpack(format, string)

string format .
calcsize(format)

(.. ), format.

Format C Type
c
?
i
l
f
d
s

char
Bool
Int
Long
float
double
char[]

Python
string of length 1
bool
integer
integer
float
float
string

, . ,
'4h' 'hhhh'.
,
.
's' , .
'10s' 10 , '10c' 10 .
:
< - little-endian
> - big-endian

58

float,
, , :
from struct import *
out = open("123.bin", "wb")
format = "if5s"
data
= pack(format, 24,12.48,'12345')
out.write(data)
out.close()
input = open("123.bin", "rb")
data = input.read()
input.close()
format = "if5s"
# one integer
value,value2,value3 = unpack(format, data) # note the ',' in 'value,':
unpack apparently returns a n-uple
print value
print value2
print value3
print calcsize(format)
>>>
>>>
>>>
>>>

24
12.4799995422
12345
13

10.
os .
. os.getcwd :
import os
cwd = os.getcwd()
print cwd

:
os.path.exists('my_file')

:
os.listdir(path)

:
import os
def walk(dir):
for name in os.listdir(dir):
path = os.path.join(dir, name)
if os.path.isfile(path):
print path
else:
walk(path)
walk(path)

:
, , . os.path.walk
: , , :

59

import os, sys


def getlocaldata(sms,dr,flst):
for f in flst:
fullf = os.path.join(dr,f)
if os.path.islink(fullf): continue # don't count linked files
if os.path.isfile(fullf):
sms[0] += os.path.getsize(fullf)
sms[1] += 1
else:
sms[2] += 1
def dtstat(dtroot):
sums = [0,0,1] # 0 bytes, 0 files, 1 directory so far
os.path.walk(dtroot,getlocaldata,sums)
return sums
report = dtstat('.')
print report

grep.
, 'import os':
import os, sys, fnmatch
mask = '*.py'
pattern = 'import os'
def walk(arg,dir,files):
for file in files:
if fnmatch.fnmatch(file,mask):
name = os.path.join(dir,file)
try:
data = open(name,'rb').read()
if data.find(pattern) != -1:
print name
except:
pass
os.path.walk('.',walk,[])

, /.
. .
/ . .
.

. / ,
.
, .
2.6.


; open-source
www.iakovlev.org. .

60

Python: 9.

, ,

; open-source
www.iakovlev.org. .
:
, .

.

. :
.
,
.
exec fork.
.
.
.
, .
.

.
.
.
(Queue).
(Lock).

1.
subprocess, ,
(pipe).
, ,
. arent.py
child.py. parent.py. Child.py command,
. ,
. child.py,
word .
subprocess.
. , child .

61

parent.py:
import os
import subprocess
import sys
child = os.path.join(os.path.dirname(__file__), "./child.py")
word = 'word'
file = ['./parent.py','./child.py']
pipes = []
for i in range(0,2):
command = [sys.executable, child]
pipe = subprocess.Popen(command, stdin=subprocess.PIPE)
pipes.append(pipe)
pipe.stdin.write(word.encode("utf8") + b"\n")
pipe.stdin.write(file[i].encode("utf8") + b"\n")
pipe.stdin.close()
while pipes:
pipe = pipes.pop()
pipe.wait()

child.py:
import sys
word = sys.stdin.readline().rstrip()
filename = sys.stdin.readline().rstrip()
try:
with open(filename, "rb") as fh:
while True:
current = fh.readline()
if not current:
break
if (word in current ):
print("find: {0} {1}".format(filename,word))
except :
pass

2.
, ,
(threads).
. (multi-threading) ,
.
,
. , , .
:
for x in L

.
: , .

62

.
, , .
(deadlock) .
: . ,
.
,
. .
, .
.
, ,
, .
,
.
.
.
(GIL), .
.
, /,
, , ,
.

3.
threading.
:

threading.Thread()


threading.Thread

, :
import threading
import time
def clock(interval):
while True:
print("The time is %s" % time.ctime())
time.sleep(interval)
t = threading.Thread(target=clock, args=(15,))
t.daemon = True
t.start()

:
. start() -,
run():

63

import threading
import time
class ClockThread(threading.Thread):
def __init__(self,interval):
threading.Thread.__init__(self)
self.daemon = True
self.interval = interval
def run(self):
while True:
print("The time is %s" % time.ctime())
time.sleep(self.interval)
t = ClockThread(15)
t.start()

:
start()
run()

, .

, , ,
, . timeout ( )
( ),
, join . join()
. join() .
.
join([timeout])

getName()

setName(name)
isAlive()

name.

, ( run() ).

isDaemon()

, .

setDaemon(daemonic)

daemonic , .

Thread.
len(threading.enumerate()).
activeCount()

-, .. ,
.
currentThread()

enumerate()

4. (Queue)
,
: ,
grep. work_queue ,
. Queue, :

64

import threading
import Queue
class Worker(threading.Thread):
def __init__(self, work_queue, word):
super(Worker,self).__init__()
self.work_queue = work_queue
self.word = word
def run(self):
try:
filename = self.work_queue.get()
self.process(filename)
finally:
pass
def process(self, filename):
previous = "
current=True
with open(filename, "rb") as fh:
while current:
current = fh.readline()
if not current: break
current = current.decode("utf8", "ignore")
if self.word in current :
print("find {0}: {1}".format(self.word,filename))
previous = current
word = 'import'
filelist = ['./file1.py','./file2.py','./file3.py']
work_queue = Queue.Queue()
for filename in filelist:
work_queue.put(filename)
for i in range(3):
worker = Worker(work_queue, word)
worker.start()

5. (Lock)
,
Web-.
url_list threading.Lock().
Lock :
. blocking
, .
acquire([blocking=True])

, .
blocking , True ( ).
(.. blocking=False), True,
. False.
release()
locked()

(True , False ).

65

import threading
from urllib import urlopen
class WorkerThread(threading.Thread):
def __init__(self,url_list,url_list_lock):
super(WorkerThread,self).__init__()
self.url_list=url_list
self.url_list_lock=url_list_lock
def run(self):
while (1):
nexturl = self.grab_next_url()
if nexturl==None:break
self.retrieve_url(nexturl)
def grab_next_url(self):
self.url_list_lock.acquire(1)
if len(self.url_list)<1:
nexturl=None
else:
nexturl = self.url_list[0]
del self.url_list[0]
self.url_list_lock.release()
return nexturl
def retrieve_url(self,nexturl):
text = urlopen(nexturl).read()
print text
print '################### %s #######################' % nexturl
url_list=['http://linux.org.ru','http://kernel.org','http://python.org']
url_list_lock = threading.Lock()
workerthreadlist=[]
for x in range(0,3):
newthread = WorkerThread(url_list,url_list_lock)
workerthreadlist.append(newthread)
newthread.start()
for x in range(0,3):
workerthreadlist[x].join()

,
.
.
,
.
.

, .
, .
2.6.

66

Python: 10.

, ,

; open-source
www.iakovlev.org. .
: Python.
.
. ,
: , , ,
Web-, , , CGI- .. ,
, .
Python. socket
. C/C++ ,
. Python : httplib, ftplib, telnetlib, smtplib,
. ,
twisted, ,
.
.
1.
2.
3.
4.
5.
6.
7.

TCP -.
TCP-.
Twisted.
Twisted .
Twisted .
Twisted -.
Twisted -.

1. TCP -
TCP .
, ,
.
- . socket
, .
, .
: ,
. : ,
-, TCP-.
, bind(), ip- .
, .
listen() ,
.

67

accept() ,
.
.
recv() .
.
send() .
close() .
raw_input() .
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'localhost'
port = 8007
s.bind((host), (port))
s.listen(1)
conn, addr = s.accept()
data = conn.recv(1000000)
print 'client is at', addr , data
conn.send(data)
z = raw_input()
conn.close()

, . connect()
. send() .
recv() . close() .
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'localhost'
port = 8007
s.connect((host, port))
s.send('hello')
data = s.recv(1000000)
print 'received', data, len(data), 'bytes'
s.close()

? , (wrappers)
. , socket.send() send()
.
(chunk).
, send() , ,
.
, , .
,
.

68

2. TCP-
, accept()
. , ,
. ,
. :
1. ;
2. ;
3. select/poll.
Python setblocking()
, .
:
lstn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cs = []
nc = 2
for i in range(nc):
(clnt,ap) = lstn.accept()
clnt.setblocking(0)
cs.append(clnt)

, .
select()
. poll().

3. Twisted
Twisted - , Python.
, .
mail, web, news, chat, DNS, SSH, Telnet, RPC, ..
Linux twisted.
, : http://twistedmatrix.com/projects/core/
Twisted event. ,
event handler.
event loop. ,
. .
event loop twisted , reactor,
twisted.internet . :
reactor.run()

69

4. Twisted Protocol
Protocol,
twisted.internet.protocol.Protocol. .
, . :
from twisted.internet.protocol import Protocol
class Echo(Protocol):
def dataReceived(self, data):
self.transport.write(data)

. , ,
. , connect:
from twisted.internet.protocol import Protocol
class Connector(Protocol):
def connectionMade(self):
self.transport.write("Connection made ... \r\n")
self.transport.loseConnection()

, . connectionMade
. connectionLost .

5. Twisted Factory
Factory,
twisted.internet.protocol.Factory. ,
.
, , factory, .
, -:
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
class LoggingProtocol(LineReceiver):
def lineReceived(self, line):
self.factory.fp.write(line+'\n')
class LogfileFactory(Factory):
protocol = LoggingProtocol
def __init__(self, fileName):
self.file = fileName
def startFactory(self):
self.fp = open(self.file, 'a')
def stopFactory(self):
self.fp.close()

70

6. Twisted Client-Server
: dataReceived
:
from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor
class Server(Protocol):
def connectionMade(self):
self.transport.write(self.factory.quote+'\r\n')
def connectionLost(self, reason):
print 'connection lost ...'
def dataReceived(self, data):
print data
self.transport.write(data)
class ServerFactory(Factory):
protocol = Server
def __init__(self, quote=None):
self.quote = quote
reactor.listenTCP(8007, ServerFactory("quote"))
reactor.run()


, callLater:
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, ClientCreator
class Client(Protocol):
def sendMessage(self, msg):
self.transport.write("%s\n" % msg)
for i in range(1,5):
self.transport.write("%d\n" % i)
def dataReceived(self, data):
print data
def gotProtocol(p):
p.sendMessage("Hello")
reactor.callLater(1, p.sendMessage, "world")
reactor.callLater(2, p.transport.loseConnection)
c = ClientCreator(reactor, Client)
c.connectTCP("localhost", 8007).addCallback(gotProtocol)
reactor.run()

:
Hello
1
2
3
4
world
1
2
3
4
connection lost ...

71

7. Twisted -
- , ,
.
, ,
, .
clientProtocols. connectionMade
ChatProtocol . -:
from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory
from twisted.protocols.basic import LineOnlyReceiver
class ChatProtocol(LineOnlyReceiver):
name = ""
def getName(self):
if self.name!="":
return self.name
return self.transport.getPeer().host
def connectionMade(self):
print "New connection from "+self.getName()
self.sendLine("Welcome to my my chat server.")
self.sendLine("Send '/NAME [new name]' to change your name.")
self.sendLine("Send '/EXIT' to quit.")
self.factory.sendMessageToAllClients(self.getName()+" has joined the party.")
self.factory.clientProtocols.append(self)
def connectionLost(self, reason):
print "Lost connection from "+self.getName()
self.factory.clientProtocols.remove(self)
self.factory.sendMessageToAllClients(self.getName()+" has disconnected.")
def lineReceived(self, line):
print self.getName()+" said "+line
if line[:5]=="/NAME":
oldName = self.getName()
self.name = line[5:].strip()
self.factory.sendMessageToAllClients(oldName+" changed name
to "+self.getName())
elif line=="/EXIT":
self.transport.loseConnection()
else:
self.factory.sendMessageToAllClients(self.getName()+" says "+line)
def sendLine(self, line):
self.transport.write(line+"\r\n")
class ChatProtocolFactory(ServerFactory):
protocol = ChatProtocol
def __init__(self):
self.clientProtocols = []
def sendMessageToAllClients(self, mesg):
for client in self.clientProtocols:
client.sendLine(mesg)
print "Starting Server"
factory = ChatProtocolFactory()
reactor.listenTCP(12345, factory)
reactor.run()

72

telnet:
>> telnet localhost 12345

, TCP
. TCP -
. ,
. select() poll()
.
twisted ,
,
.
Python 2.6.


; open-source
www.iakovlev.org. .

73

Python: 11. Web: Django


, ,

; open-source
www.iakovlev.org. .
: Python
Django. ,
, Python Django .


-- (Model-View-Controller) MVC,
.
: .
Web-,
MVC. ,
Web-, Web-.
:

(url);
;
.

- .
1. : Web-.
,
. .
- (ORM)
. ORM,
SQL.
, -. .
, Web.
2. (view): ,
, . View
, - (url)
.
3. : .
.
4. URL: (view).
.
,
. :
.

74

, , ,
- . . , ,
: , , ,
. , :
http://projects.washingtonpost.com/congress/
http://www.ljworld.com/
http://www.lawrence.com/
.
1.
2.
3.
4.
5.
6.

.
.
.
.
.
.

1.
, 2.3.
-: ,
:
http://www.djangoproject.com/download/.
:
setup.py install

, :
> import django

:
> django.VERSION

1.1.1.

2.
:
django-admin.py startproject mysite

mysite, .
:
75

mysite/
__init__.py
manage.py
settings.py
urls.py

__init__.py ,
.
manage.py , .
settings.py .
urls.py .
Web-, :
python manage.py runserver

:
Validating models...
0 errors found.
Django version 1.1, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

http://127.0.0.1:8000/, ,
: .

3.
: PostgreSQL, SQLite, MySQL, Microsoft SQL
Server, Oracle.
, ,
. , ,
. settings.py :
DATABASE_ENGINE = 'postgresql_psycopg2'
DATABASE_NAME
= 'mysite'
DATABASE_USER
= 'postgres'
TIME_ZONE = 'Europe/Moscow'
LANGUAGE_CODE = 'ru-ru'

, mysite , ,
:
psql -d template1 -U postgres -c "DROP DATABASE mysite;"
psql -d template1 -U postgres -c "CREATE DATABASE mysite
WITH OWNER postgres ENCODING='UNICODE';"

, 10 :
python manage.py syncdb

76

4.
Web-:
python manage.py startapp People

mysite People :
People/
__init__.py
models.py
tests.py
views.py

settings.py , :
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'mysite.People'
)

settings.py :
ROOT_URLCONF = 'mysite.urls'

Person , -.
models.py:
from django.db import models
class Person(models.Model):
name = models.CharField('name', max_length=200)
email = models.EmailField('Email', blank=True)
def __str__(self):
return '%s' % (self.name)

, .
:
python manage.py syncdb

. ,

, :
. sql-
.
, - views.py:
from django.shortcuts import HttpResponse
from mysite.People.models import Person
def index(request):
html = "<H1>People !!!</H1><HR>"
return HttpResponse(html)

77

urls.py:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^People/$', 'mysite.People.views.index')
)

Web-:
python manage.py runserver

:
http://127.0.0.1:8000/People/

5.
mysite templates. settings.py :
TEMPLATE_DIRS = (
"/home/mysite/templates"
)

. person.htnl
:
<H1>People !!!</H1><HR>
<table width=100%>
<tr><td colspan="3">
Personal Information
</td></tr>
<tr valign="top"><td width=30%>
<li>Name: {{p.name}}</li>
</td>
<td width=30%>
<li>Email: {{ p.email }}</li>
</td></tr>
</table>

index : Person
.
:
{{p.name}}
{{p.email}}

views.py :
from mysite.People.models import Person
from django.shortcuts import render_to_response, get_object_or_404
def index(request):
person = Person()
person.name = 'Alex'
person.email = 'Alex@gmail.com'
return render_to_response('person.html', {'p': person})

78

Web- .

6.
.
settings.py:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'mysite.People',
'django.contrib.admin'
)

,
:
python manage.py createsuperuser

:
python manage.py syncdb

urls.py :
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
(r'^People/$', 'mysite.People.views.index')
)

Web-:
python manage.py runserver

: http://127.0.0.1:8000/admin/. .
.
.

, , .
, MVC,
,
, .. Web-
: http://www.djangoproject.com/
. .
: , .
. ,
,
, .
79

:
PyUnit(unittest)
, ,
: ,
.


, unittest, .
(Test fixture). ,
, (test case).
(test case),
. , .
(test suite) unittest. Test Suite
, .
, .
(test runner). ,
.
.


. .
, , ,
python 2.6.
random ( 1).
1.
#!/usr/bin/env python
#-*- coding:cp1251 -*import unittest
import random
class TestSequenceFunctions(unittest.TestCase):
def testshuffle(self):
'''
, shuffle

'''
self.seq = range(10)
random.shuffle(self.seq)
self.assertNotEqual(self.seq, range(10))
if __name__=="__main__":
unittest.main()

80

(
2).
2. 1
.
----------------------------------------------------------Ran 1 test in 0.000s
OK

, ,
( , , ,
unittest.main()).
, ,
, .
TestSequenceFunctions.
testshuffle.
! , test.
, , 0 () .
test , -
, .
, : _testshuffle.
.
1. . self.seq = range(10)
2. shaffle random. random.shuffle(self.seq)
3.
.
. , ,
, . ,
TestCase, , , ,
, .
. choice random.
choice .
TestSequenceFunction ( 3).
3. choice
def testchoice(self):
'''
choice

'''
self.seq = range(10)
element = random.choice(self.seq)
self.assert_(element in self.seq)

81

, , testshaffle.
. ,

unittest.TestCase, ,
. TestCase 20 .
,
. .
.


. ,
, , .

. .
, . ,
, .

,
. ,
, . , ?
unittest.TestCase setUp tearDown,
. , ( 4).
4. setUp tearDown
#!/usr/bin/env python
#-*- coding:cp1251 -*import unittest
import random
class TestSequenceFunctions(unittest.TestCase):
def setUp(self):
self.seq = range(10)
def testshuffle(self):
'''
, shuffled

'''
random.shuffle(self.seq)
self.assertNotEqual(self.seq, range(10))
def testchoice(self):
'''
choice

'''
element = random.choice(self.seq)
self.assert_(element in self.seq)
def tearDown(self):
del self.seq
if __name__=="__main__":
unittest.main()

82

4 setUp tearDown.
.
setUp . tearDown ,
.
,
.
, , ,
, , ,
.


.
python ,
. ,
, ?
unittest.TestCase?

. , setUp tearDown.
unittest.TestCase.
. ,
.
. , ,
. ,
?
, , .
. , python
(TestSuit).
unittest.TestSuit
, addTest addTests, .
(TestCase), (TestSuit), 5.
5. TestSuit
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(testEx1))
suite.addTest(unittest.makeSuite(testEx2))

unittest.TestSuite().
testEx1 testEx2 .
, ,
. :

83

suite.addTest (suite1),

suite1 , , , testEx3, testEx4 ..


suite2, suite3.
, suit.
testEx1, testEx2, testEx3 .., .



( 6).
6.
if __name__==__main__:
unittest.main()

main() unittest
.
main() , ,
.
:
[] []

:
;
[] , (. 1);
[] / .

1. unittest.main


-h --help
-v --verbose
-q --quiet
, testex1.py ( 7).

84

7.
import unittest
import ex1.py
class testEx1(unittest.TestCase):
def setUp(self):
...
...
def testex11(self):
...
...
...
def testex12(self):
...
...
...
if __name__=="__main__":
unittest.main()

testex1.py unittest.main(),
8.
8. main
..
----------------------------------------------------------Ran 1 test in 0.000s
OK

. , -
, 'F'. ,
, 'E',
.
- ,
v --verbose ( 9).
9. main
#> textex1.py v
testex11 (__main__.testex1) ... ok
testex11 (__main__.testex1) ... ok
----------------------------------------------------------Ran 1 test in 0.000s
OK

unittest.main , ,
.
. ,
. unittest TestRunner(),
, .
,
python.
85


,
. ,
(assertsion),
Python (
).

86