一. 字符串的操作
1. Django用到的一部分字符串方法:
字符串方法 | 描述 |
count | 字符串中子串出现的次数 |
find | 查找字符串(index,rfind,rindex) |
join | 用一种分隔符合并字符串 |
replace | 查找替换子串 |
split | 将字符串分隔成子串(splitlines) |
startswith | 字符串是不是以子串开头(另请参见endswith) |
strip | 移除行首行尾的空白符(另请参见rstrip,lstrip) |
title | 大写每个单词第一个字母(另请参见capitalize,swapcase) |
upper | 大写整个字符串(lower) |
isupper | 字符串是大写的么(islower) |
2. 字符串提示符
python字符串可以在引号前面放一个标识符:
r代表这是一个raw字符串,告诉解释器不要转换字符串中的任何字符,在正则表达式中非常常用。(注:正则表达式常用处理字符串,大量使用了特殊字符)
u代表这是一个Unicode字符串。Unicode是一种新型字符集,拥有大量编码方式。在Django中每个部分都支持Unicode
二. 元组
元组的主要作用:作为参数传递给函数调用,或是从函数调用那里获得参数时保护其内容不被外部接口修改。在后台应用频繁(django配置文件中使用很多)。
注:元组是由逗号决定的。单个元素的元组在最后必须跟一个逗号,有时元组外围的括号可以省略,但逗号不能省。
很多Django的配置都是用元组来指定的——admin选项、URLconf规则,以及很多在setting.py中的设置。
内置序列函数和工厂函数
与数字一样,所有序列类型都有一个特殊的工厂函数来复杂创建所需类型的实例
函数 | 描述 |
str | (可打印的)字符串表示(参见repr,unicode) |
list | 列表表示 |
tuple | 元组表示 |
len | 对象的势(笔者用来计算字符串或者list的长度) |
max | 序列中“最大的”对象(参见min) |
range | 给定范围内可迭代的数字(参见enumerate,xrange) |
sorted | 返回排好序的列表(参见reversed) |
sum | 序列值加和(数字) |
any | 是不是有元素为True(参见all) |
zip | 返回N个元组的迭代器,其中每个元素包含了N个序列里对应的元素 |
三. 映射类型:字典
字典是python里唯一的映射类型。字典是可变的、无序的、大小可变的键值映射,有时也称散列表或关联数组。字典用 “{}” 定义。字典是python里最重要的数据结构。
字典是无序的,所以字典在查找元素时的非常高效。
常用的Python字典方法:
字典方法 | 描述 |
keys | 所有键(另请参见iterkeys) |
values | 所有值(另请参见itervalues) |
items | 所有键-值对(另请参见iteritems) |
get | 获取给定键的值或默认值(另请参见setdefault,fromkeys) |
pop | 从字典里移除键并返回值(另请参见clear,popitem) |
updata | 用另一个字典更新字典 |
列表和字典(dict)是应用程序里用的最频繁的数据结构,元组和字典主要是用在函数调用之间交换参数和返回值。字符串也时有用到。(Django常用)
四. 异常处理
处理程序:try—except
如果运行时发生异常的话,解释器会查找相应的处理语句(handler)。要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看能不能处理。如果在最外层(全局“main”)还没有找到的话,解释器就会退出,同时打印出traceback以便让用户找出错误产生的原因。
下面是为多个异常创建的多个处理语句:
try:
process_some_data()
except (TypeError,ValueError), e:
#括号里面是装在元组里面的异常类型,出现异常时执行except下的内容
print "error :you provide invalid data", e
except Exception, e:
#Exception是(几乎)所有异常根类
print "error :you provide invalid data", e
#如果有异常没有被他之前的任何语句捕捉的话,这个异常会在最后一个语句里被处理
子句:try—finally
不关心捕捉到什么错误,无论错误是不是发生,这些代码“必须执行”,比如关闭文件、释放锁、把数据库链接返还给连接池等。这时就要用子句了
try:
get_mutex()
do_some_stuff()
finally:
free_mutex()
#没有发生异常时,finally中的代码会在try完成之后立即运行。
#如果发生任何错误,finally的代码还是会执行
注:finally可以和except一起使用
常见的Python异常:
异常 | 描述 |
AssertionError | assert(断言)语句失败 |
AttributeError | 试图访问一个对象没有的属性,比如foo.x,但是foo没有属性x |
IOError | 输入/输出异常;基本上是无法打开文件 |
ImportError | 无法引入模块或者包;基本上是路径问题 |
IndentationError | 语法错误;代码没有正确对齐 |
IndexError | 下标索引超出序列边界 |
KeyError | 试图访问字典里不存在的键 |
KeyboardInterrupt | Ctrl+C被按下 |
NameError | 使用一个还未被赋予对象的变量 |
SyntaxError | Python非法代码,代码不能编译 |
TypeError | 传入对象类型于要求不符 |
UnboundLocalError | 试图访问一个还未被设置的局部变量,基本上是由于另一个同名的全局变量,导致 |
你以为正在访问它 | |
ValueError | 传入一个调用者不期望的值,即使值的类型是正确的 |
五. 装饰器
装饰器指的是一种让你能改变或者说“装饰”函数行为的机制,它能让函数执行一些和原本设计不同,或是在原有基础上额外的操作。装饰器也可以说是对函数的一个包装。这些额外的任务包括写日志、计时、过滤等。
Python里一个被包裹或被装饰的函数(对象)通常会被重新赋值给原来的名字,这样被包裹的函数能和普通的版本保持兼容——因为使用装饰器就是在现有的功能上再“加盖”额外的功能。
#装饰器
def log(func):
def wrappedFunc():
print("*** %s() called" % func.__name__)
return func()
return wrappedFunc
#包装后的函数
@log
def foo():
print("inside foo()")
装饰器的优点是可以用一个简单的@符号完成接收对象、修改并重新赋值给原来的变量的操作。
注:装饰器教程参见Kent John的“Python Decorators”教程,http://personalpages.tds.net/~kent37/kk/00001.html。
六. 面向对象编程
(主要是类的用法,笔者会用普通的类,再深入的一直理解的不太好)
1. 实例化
Python创建实例只要调用类的名字即可。Python用的“初始化程序(initializer)而不是”构造函数“(constructor),名字是__init__。
Python会为每个实例调用__init__,随后返回这个对象。
*Python还支持动态实例属性,即那些没有在类定义里声明的属性,可以”凭空“创造出来。
2.继承
创建一个子类和创建一个类是很相似的,你只需要提供一个或多个基类(不是对象)即可。
john = AddressBookEntry("John Doe", "408-555-1212")
#父类
class EmployeeAddressBookEntry(AddressBookEntry):
#AddressBookEntry 就是EmployeeAddressBookEntry 的继承父类
def __init__(self, name, phone, id, social):
AddressBookEntry.__init__(self,name,phone)
self.empid = id
self.ssn = social
子类会继承父类的一切。Django在其内部以及用户关心的外部特征里也都大量使用了继承。
3.嵌套类
就像用来创建装饰器的”嵌套函数“一样,创建嵌套类,即在类的内部定义类。只有在MyClass实例的内部才可见。
class MyClass(object):
class InnerClass:
pass
在Django里唯一一个可能用上的嵌套类是Meta嵌套类。
七. 正则表达式
Django使用正则表达式的字符串匹配机制来定义网站的URL(统一资源定位符)。如果没有正则表达式(regex),将不得不定义每一个可能的URL,在对/index/或/blog/posts/new/的时候还好,但是遇上稍微动态一点的URL,像/blog/posts/2008/05/21/这样的URL就很麻烦了。
这里只简单介绍,内容很多,之后再开新的笔记详细介绍。
八. 常见错误
1.单元素的元组
单元素的元组在元素末尾一定要加”,“
2.模块
import random 和 from random import choice 没有性能上的差异,没有节省内存。两种方法中,整个模块都已经被导入了,但第二种方法只有那个函数的引用被保存了下来。
模块是可以重复导入的,但每个模块只能加载一次。
3.可变性
注:新手雷区啊!!!
所有Python对象都有三个属性:类型、标识符、值。所有三个属性几乎总是只读的,即在对象的生命期间他们是不可改变的。唯一的例外就是对象的值:如果对象的值可以改变,他就是可变对象,反之就是不可变对象。
简单类型或者”标量(scalar)“类型,包括整数等其他数字类型,str和unicode这样的字符串类型,以及元组都是不可变的。列表、字典、类、类实例等都是可变的。
可变对象如何影响方法调用?
例如:list.sort是直接在列表上排序而不是返回它。
reversed和extend,以及字典的Update等也都是直接的修改对象。
复制对象和可改变性:
不可变对象是传值的,可变对象是穿引用的。即不可变对象(即整数)被真正复制,而可变对象只是复制了一个对它们的引用,即在内存中只有一份对象,而有两份引用。
>>> mylist = [1, 'a', ['foo', 'bar']]
>>> mylist2 = list(mylist)
#由于mylist的第三个对象是一个列表,而列表是可变的,所以mylist2得到的只是一份引用,
#任何一个父列表中修改它都会影响到另一个,这种复制类型称为 “浅拷贝”