Python Web Development With Django

第一部分入门

第l章Django Python实战

1.1Python技术就是Django技术
1.2人门:Python交互解释器

ipython

1.3Python基础
1.4Python标准类型
bool
数字

int - 无long
float - 无double
complex
通过decimal模块访问十进制浮点

内置工厂函数

int
round
divmod
ord
chr

序列sequence和迭代tuple

list
string
tuple

  • 序列切片
>>> s = 'Python'
>>>s[1:4]
'yth'
>>> s [2:4]
'th'
>>> s[:4]
'Pyth'
>>> s [3 :]
'hon'
>>> 8[3:-1]
'ho'
>>> s [:]
'python'
>>> str(s)
'Python'
>>> 'abc' + 'def'
'abcdef'
>>> 'abc' * 3
'abcabcabc'

相比listl += list2
以下的方式要好得多:
'%s%s' % ('foo', 'bar')
.join(['foo' , 'bar'])
lístl.extend(list2)
列表
>>> book = ['Python' , 'Development' , 8] # 1) 创建列表
>>> book.append(2008) # 2) 附加对象
>>> book.insert(l , 'Web') # 3) 插入对象
>>> book
['Python' , 'Web' , 'Developrnent' , 8, 2008J
>>> book[:3] # 4) 切片头三个元素
['Python' , 'Web' , 'Developrnent']
>>> 'Django' in book # 5) 对象属于列表吗?
False
>>> book.rernove(8) # 6) 显式移除对象
>>> book.pop(-l) # 7) 通过索引移除对象
2008
>>> book
[ I Python' , I Web' , 'Developrnent' J
>>> book * 2 # 8) 重复/复制
['Python' , 'Web' , 'Development' , 'Python' , 'Web' , 'Development'J
>>> book.extend ([''with', 'Django']) # 9) 合并到当前列表
>>> book
['Python' , 'Web' , 'Development' , 'with' , 'Django']
>>> book = ['Python' , 'Web' , 'Development' ,8, 2008]
>> book.sort() #注意:这是直接排序,没有返回值!
>> book
[8 , 2008, 'Development' , 'Python' , 'Web']

无返回值

  • sort
  • append
  • insert

返回列表

  • sorted
  • reversed
列表推导式

(Iist comprehension or listcomps from Haskell)

#for
>>> data = [x + 1 for x in range(10)]
>>> data
[1 , 2, 3, 4, 5, 6, 7, 8, 9, 10)
 
#filter
>>> even_numbers = [x for x in range(10) if x % 2 == 0]
>>> even numbers
[0, 2, 4, 6, 8]
生成器表达式

(generator expression)
惰性计算 (lazy evaluation)

>>> even_numbers = (x for x in range(10000) if x 告2 == 0)
>>> even numbers
<generator object at Ox . ..>
字符串
>>> s = 'Django is cool' # 1
>>> work = s.split() # 2
>>> words
['Django' , 'is' , 'cool']
>>> ' '.join(words) #3
'Django is cool'
>>> '::' .join(words) #4
'Django::is::cool 
>>> ".join(words) #5
'Djangoiscool'
>>> s. upper () #6
'DJANGO IS COOL'
>>> s.upper() . isupper() # 7
True
>>> s.title() #8
'Django Is Cool'
>>> s.capitalize() #9
'Django is cool'
>>> s.find('go') # 10
4
>>> s.fínd('xxx') # 11
-1
>>> s.startswith('Python') # 12
False
>>> s.replace('Django' , 'Pthon') # 13
'python ís cool'

表1.3 常用的Python字符串方法

字符串方法 描述
count 字符串中子串出现的次数
find 查找子串(类似的还有index 、rfind 、rindex)
join 用一种分隔符合并子串
replace 查找替换子串
split 将字符串分隔成子串(类似的还有splitlines)
startswith 字符串是不是以子串开头(另请参见endswith)
strip 移除行首行尾的空白符(另请参见rstrip 、lstrip)
title 大写每个单词第一个字母(另请参见capitalize 、swapcase)
upper 大写整个字符串(类似的有lower)
lsupper 字符串是大写的么? (类似的还有islower 等)
字符串指示符

(designator)
u - unicode
r - raw

>>> mystring = u' This is Unicode! '
>>> mystring
u'This is Unicode!'
 
filenarne = r'C:\ternp\newfolder\robots.txt'
 
>>> Is is nurnber %d' 告(5[:6J , 1)
'Django i5 nurnber l'
>>> hi = '" hi
there' , ,
>>> hi
'hi \nthere '
>>> print hi
hi
there
 
xml = '"
  < ?xml version=" 1.0"?>
    <Request version="%.1f">
      <Header>
        <APIName>PWDDapp</APIName>
        <APIPassword>youllneverguess</APIPassword>
      </Header>
      <Data>
      </Data>
    </Request>
'"
 
VERSION = 1.2
sendXML(xml % (VERSION))
元组

tuple

>>> a = ("one ll , 刊wo")
>>> a[O]
'one'
>>> b = (" just-one")
>>> b [0]
'j ,
>>> c = ("just-one" ,)
>>> c [0]
'.j ust-one'
>>> d =叮ust-one" ,
>>> d [0]
'just-one'
内直序列函数和工厂函数
函数 描述 可迭代:序列、迭代器、生成器、字典键值、文件行
str (可打印的)字符串表示(参见repr , unicode)
list 列表表示
tuple 元组表示
len 对象的势
max 序列中"最大的"对象(参见min)
range 给定范围里可迭代的数字(参见enumerate , xrange)
sorted 返回排好序的列表(参见reversed)
sum 序列值加和(数字)
any 是不是有元素为True? (参见all)
zip 返回N个元组的迭代器,其中每个元组包含了N个序列里对应的元素。
>>> zip ([ 1, 2 , 3] , (' a " 'b' , 'c'))
[(1 , 'a') , (2 , 'b') , (3 , 'c')]
映射类型:字典
>>> book = { 'title': 'Python Web Development' , 'year': 2008 }
>>> book
('year': 2008 , 'title': 'Python Web Develop阳lt' 1
>>> 'year' in book
True
>>> 'pub' in book
False
>>> book.get ('pub' , 'N/A')
'N/A'
>>> book['pub') = 'Addison Wesley'
>>> book.get ('pub' , 'N/A')
'Addison Wesley'
>>> for key in book:
print key, ':', book [key]
year : 2008
pub : Addison Wesley
title : Python Web Development
 
>>> d = { 'title': 'Python Web Development' , 'year': 2008 }
>>> d.setdefault ('pub' , 'Addison Wesley')
'Addison Wesley'
>>> d
{'year': 2008 , 'pub': '且ddison Wesley' , 'ti t1e': 'Python Web Development'}
 
>>> del d['pub']
>>> d['title'] = 'Python Web Development with Django'
>>> d
{'year': 2008 , 'title': 'Python Web Development with Django' }
>>> len (d)
2
字典方法 描述
keys 所有键(另请参见iterkeys)
values 所有值(另请参见itervalues)
Ilems 所有键一值对(另请参见iteritems)
get 获取给定键的值或默认值(另请参见setdefault 、fromkeys)
pop 从字典里移除键并返回值(另请参见clear 、P阴opμit怡em
update 用另一个字典更新字典
1.5流程控制
data = raw_input("Enter 'y' or 'n': ,,)
if data[O] == 'y':
  print "You typed 'y'."
elif data[O] == 'n'
  print "You typed 'n'"
else:
  prìnt 'Invalìd key entered!'
 
#循环
for lìne in open('/tmp/some_file.txt'):
  if 'error' in line:
    print line
 
>>> data = (123 , 'abc' , 3.14)
>>> for í , value in enumerate(data):
         print í , value
o 123
1 abc
2 3.14
1.6异常处理
try:
  get_mutex()
  do some stuff ()
except (IndexError, KeyError, AttributeError) , e:
  log("ERORR: data retrieval accessing a non-existent element")
  raise TypeError ("ERROR foo (): must pass in an integer!")
finally:
  free mutex ()
异常 描述
AssertionError assert (断言)语句失败
Attribut巳Error 试图访问一个对象没有的属性,比如foo人但是foo没有属性x
IOError 输入/输出异常:基本上是无讼打开文件
ImportError 无法引人摸块或者包s 基本上是路径问题
IndentationError 语法错误;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x 只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
Keyboardlnteπupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译
TypeError 传人对象类型与要求的不符
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有-个同名的全局变量,导致你以为正在访问它
ValueError 传人一个调用者不期望的值,即使值的类型是正确的
  • 1.7文件
>>> f = open( 'test. txt' , 'w')
>>> f. wrìte (' foo\n' )
>>> f. write ( 'bar\n' )
>>> f. close ()
>>> f = open('test.txt' , 'r')
>>> for line in f
      print line.rstrip()
foo
bar
>>> f .close ()
1.8函数
  • 声明和调用函数
>>> def foo(x):
      print x
>>> foo(123)
123
  • (函数调用里的)关键宇参数

check_web_server(port=80 , path= 小, host='www.python.org')

  • (函数签名里的)默认参数

def check web server(host , port=8 日, path=' / ' ) :

  • 函数是first-class的对象

在Python里你可以把函数(和方法)当作和其他对象一样的使用,例如,把它们存放在容器里,赋值给其他变量,作为参数传递给函数等。
唯一的不同是你可以这个函数对象,就是说当附上括号和参数时,你就把它当作了一个函数来对待。

>>> foo = 42
>>> def bar(}:
print "bar"
 
>>> baz = bar
>>> bar{)
bar
>>> baz()
bar
 
>>> function_list = [bar, baz]
>>> for function in function list:
function ()
bar
bar
  • 匿名函数和lambda

"表达式"是一个值,它的结果一定是一个Python对象。例如42 、1 + 2 、int(' 123') 、range(10)等。
结果不是对象的代码则称为"语句"。例如if或者print语句, for,while循环等。它们执行一个动作,而不是返回或生成一个值。
lambda args:表达式。在执行的时候, lambda返回一个可以立即使用的函数对象。

sorted(list_of_people , key;lambda person: person.last_namel

等价于
def get_last_name(person):
return person.last_name

sorted(list_of_people, key=get_last_name)

  • django decorator
@user_passes_test(lambda U: u.is_allowed_to_vote)
def vote(request):
II l1l1 Process a user 1s vote llllll
  • (函数调用)参数容器和变长参数 *args,**kwargs
host_info = ('www.python.org' , 80 , '/')
check_web_server(*host_info)
 
host info = {'host': 'www.python.org' , 'port': 80 , 'path', '/' )
check_web_server(**host_info)
 
daily_sales_total(5.00, 1.50, '128.75')
 
def check_web_server(host, port , path, *args, **kwargs):
...
  • 装饰器
def log(func):
  def wrappedFunc():
    print n *** %s () called" % func. name
    return func ()
  return 盯appedFunc
 
@log
def foo():
  print "inside foo()"
 
>>> foo ()
***foo () called
inside foo()

在本章稍早的地方,我们看见过这样一个接受一个参数的装饰器。
@user_passes_test(lambda u: u.is_allowed_to_vote)
在这个例子里,实际上是调用了一个函数,然后返回一个事实上的装饰器user_passes_test 自己并不是一个装饰器,它只不过是一个接受了参数的函数,然后用这些参数返回一个可用的装饰器。它的语怯是这样的:

@decomaker(deco_args)
def foo():
  pass

这个下面的代码是等价的,注意这里Python表达式是如何串联在一起的:

foo = decomaker(deco_args) (foo)

这里的产装饰器生成器(decorator-marker,或者叫decomaker) 接受参数deco_args并且返回一个可以包装foo 函数的装饰器。

@deco1(deco_args)
@deco2
def foo():
  pass
#等价于
foo= deco1(deco_args) (deco2(foo))

Reference:
http://personalpages.tds.net/~kent37/kk/00001.html

1.9面向对象编程
class AddressBookEntry(object) :
  version .= 0.1
  def init (self , name, phone):
    self. name = name
    self.phone = phone
  def update_Phone(self, phone):
    self.phone = phone
 
>>> john = AddressBookEntry{'John' , '408-555-1212')
>>> john.phone
'408-555-1212'
>>> john.update_phone{'510-555-1212')
>>> john.phone
'510-555-1212'

Python还支持动态的实例属性, 那些没有在类定义里声明的属性,可以"凭空"创造出来。

»> john.tattoo = 'Mom'

  • 继承
class EmployeeAddressBookEntry{AddressBookEntry):
  def __init__(self, name, phoneid, social):
    AddressBookEntry.__init__(selfname , phonel)
    self . empid = id
    self.ssn = social
  • 嵌套类
class MyClass(object):
  class InnerClass:
    pass
1.10正则表达式
>>> import re
>>> m = re.search(r'foo', 'seafood')
>>> print m
<_sre.SRE_Match object at ...>
>>> m.group()
'foo'
>>> m = re.search(r'bar', 'seafood')
>>> print m
None
 
>>> import re
>>> m = re.match(r'foo' , 'seafood')
>>> if m is not None: print m.group()
>>> print m
None
>>> m = re.search(r'foo' , 'seafood')
>>> if m is not None: print m.group()
'foo'
1.11常见错误
  • 模块

import random
prínt random.choice(range(10))

from random import choice
print choice(range(10))

  • Package

init.py

  • 可改变性

copy.deepcopy

  • 动态实例属性
1.12代码风格
  • 四空格对齐
  • 使用空格而非Tab
  • 不要像标题一样把一组代码写在同一行里
  • 创建文挡字符串(即"docstring") """ … """ doc help(foo)
1.13总结