Python-核心编程-学习笔记

>下划线标示符
_xxx 不用 'from module import *'导入
__xxx___ 系统定义名字
__xxx 类中的私有变量名


>模块结构和布局
(1)起始行(Unix)
(2)模块文档
(3)模块导入
(4)变量定义
(5)类定义
(6)函数定义
(7)主程序
例如:
#!/usr/bin/evn python
"this is a test module"
import sys
import os
debug = True
class FooClass(object):
'Foo class'
pass
def main():
"main function"
foo = FooClass()
if debug:
print 'ran main()'


if __name__ == "__main__":
main()


>标准类型(内建的基本数据类型)
数字
整型
布尔型
常正型
浮点型
复数型
字符串
列表
元祖
字典

>其他内建类型
类型
Null对象(None)
文件
集合/固定集合
函数/方法
模块


>每个对象天生具有布尔True或False值。
下列对象的布尔值是False
None
False(布尔类型)
所有的值为零的数
0(整型)
(浮点型)
0L(长整型)
""(空字符串)
[](空列表)
()(空元祖)
{}(空字典)
值不是上面列出来的任何对象的布尔值都是True

>代码对象是编译过的Python源代码片段,它是可执行对象。
通过调用内建函数compile()可以得到代码对象。
代码对象可以被exec命令或eval()内建函数来执行。

>帧对象:表示Python的执行栈帧。
每次函数调用产生一个新的帧,每一个帧对象都会相应创建一个C栈帧。
用到帧对象的一个地方是跟踪记录对象。

>跟踪记录对象
当异常发生时,一个包含针对异常的栈跟踪信息的跟踪记录对象被创建。

>省略对象:用于扩展切片语法中,起记号作用。


>XRange对象


>对象比较是默认是值的比较
对象本身的比较使用is/is not
a is b 等价于 id(a)==id(b) 意思是:a和b引用同一个对象

>布尔逻辑运算符
and or not

>标准类型内建函数
com(obj1, obj2) 比较obj1和obj2, 根据比较结果返回整型(-1,0,1)
repr(obj) 返回一个对象的字符串表示
str(obj) 返回对象适合可读性好的字符串
type(obj) 得到一个对象的类型,并返回相应的type对象


>比较对象的类型
方法1
if type(num) == type(5):
pass
方法2
if isinstance(num, (int, float, long, complex)):
pass
方法3
import types
if type(num) == types.IntType:
pass
方法4
from types import IntType
if type(num) == IntType:
pass


>类型和类
Python2.2统一了类型和类,所有的内建类型现在也都是类,在这基础之上原来的所谓内建转换函数,比如int(),type(),list()等现在都成了工厂函数。也就是说他们虽然看上去有点像函数,实质上他们是类。调用他们时,实际上是生成了该类的一个实例。




>对基本数据类型的3种分类模式
以存储模型为标准的分类
分类 Python类型
标量/原子类型 数值(所有的数值类型),字符串(全部是文字)
容器类型 列表,元祖,字典


以更新模型为标准的分类
分类 Python类型
可变类型 列表,字典
不可变类型 数字,字符串,元祖


以访问模型为标准的类型分类
分类 Python类型
直接访问 数字
顺序访问 字符串,列表,元祖
映射访问 字典


===============数字===================


>Python不支持的数据类型
char 或 type(可以使用长度为1的字符串来表示字符货8比特整数)
指针


>Python数字类型:整型,长整型,布尔型,双精度浮点型,十进制浮点型,复数。




> Python整型在32位系统上是32位,如果在64位机器上使用64位编译器编译Python,那么在这个系统上的整数将是64位。


>Python的长整型能表达的数值与机器支持的内存有关。


>Python中的浮点型类似C语言中的double类型,是双精度浮点数。
每个浮点数占 8 个字节(64比特)。底-52位,指数-11位,符号-1位。


>不同的数字类型相加时的强制转换规则:整数转成浮点数,非复数转成复数。
整数转成浮点数,只要在整数后面加个.0;
非复数转成复数,只要加上一个 0j 的虚数部分;


>算术运算符
1/2 地板除
1.0/2.0 真正除法


从Python2.2开始,新的运算符 // 被增加,以执行地板除:
//:不管操作数是何种数据类型,总是舍去小数部分,返回数字序列中比真正的商小的最接近的数字。
/:将执行真正的除法,需要:from __future__ import division


> 幂运算操作符比其左侧操作数的一元运算符优先级高,比其右侧操作数的一元运算符优先级低。


>简单总结(从上到下,优先级降低)
表达式1 表达式2 结果
+expr 结果符号不变
-expr 对结果符号取负
expr1 * expr2 乘以
expr1 / expr2 除以(传统除或真正除)
expr1 //expr2 地板除
expr1 % expr2 取余
expr1 + expr2
expr1 - expr2
注意:**运算符优先级高于单目运算符。


>位运算符只适用于整数。
按优先级排序为:取反~,左移<<,右移>>,与&,异或^,或|。

>数值工厂函数
bool(obj)
int(obj, base=10)
long(obj, base=10)
float(obj)
complex(str) or complex(real, img = 0.0)

>用于数值计算的5个内建函数
abs(num) 绝对值
coerce(num1, num2) 把2个参数类型转换成一致,以元祖形式返回。
divmod(num1, num2) 把除法和取余结合起来,返回一个包含商和余数的元祖。
pow(num1, num2, mod=1) 指数运算。指数运算之后再对mod取余。
round(flt, ndig=0) 四舍五入。返回与flt最接近的整数(浮点型)。nidg指定小数的位数。


>仅用于整数的函数
oct(num) 返回字符串表示的8进制整数
hex(num) 返回字符串表示的16进制整数

chr(num) 接收单字节整数,返回值对应的字符。
ord(chr) 接收一个字符,返回其对应的整数。

>对一个对象求 bool() 值时,关键看该对象所属的类中 __nonzero__() 的定义。


>rondom 模块
randrange(num1, num2, step=1) 与 range()类似,选择其中一项
uniform(num1, num2) 返回num1 num2之间的浮点数
randint(num1, num2) 返回num1 num2之间的整数
random() 返回0.0--1.0之间的浮点数
choice(seq) 返回序列 sep 中任意一项


===============序列:字符串、列表、元祖=================
>成员关系操作符 in, not in
>连接操作符 +
>重复操作符 *
>切片操作符 [],[:],[::]


>序列类型转换工厂函数
list(iter) 把可迭代对象转换成列表
str(obj) 把obj对象转换成字符串(对象的字符串表示法)
unicode(obj) 把对象转换成Unicode字符串(使用默认编码)
baseString() 抽象工厂函数,其作用仅仅是作为 str 和 unicode 函数提供父类
tuple(iter) 把可迭代对象转换成元祖


>序列类型的内建函数
enumerate(iter) 接收一个可迭代对象作为参数,返回一个 enumerate 对象(同时也是一个迭代器),该对象生成
由iter每个元素的index值和item值组成的元组。
len(seq) 返回一个序列的长度
max(iter, key=None) or max(arg0, arg1...,key=None)
返回最大值。key必须是一个可以传给sort()方法,用于比较的回调函数。
min(iter, key=None) or min(arg0, arg1...,key=None)
reversed(seq) 接收一个序列为参数,返回一个以逆序访问的迭代器。
sorted(iter, func=None, key=None, reverse=False)
接收一个可迭代对象为参数,返回一个有序列表。
sum(seq, init=0)返回seq和init的总和。
zip([it0, it1,...itN]) 返回一个列表,第一元素是it0, it1,...这些元素的第一个元素的元组。。。




>字符串的切片操作
aString[index1:index2:step]
index1: 开始字符索引的绝对位置,如果没指定代表从第一个开始
index2: 结束字符索引的绝对位置,如果没指定代表到最后一个
step: 默认为1。代表步长,如果是负数则向前步进。




>字符串一般不用成员操作符in, not in,一般使用 find(),index(),rfind(), rindex()


>字符串的拼接处理方式
1 连接号操作符+
2 字符串格式化操作符 %
3 join(seq) 方法
4 字符串模版


>格式化操作符
格式化字符 转换方式
%c 转换成字符
%r 优先用repr()函数进行字符串转换
%s 优先用str()函数进行字符串转换
%d  %i 转成有符号十进制数
%u 转成无符号十进制数
%o 转成无符号八进制数
%x  %X 转成无符号十六进制数(x/X代表转换后的十六进制字符的大小写)
%e  %E 转换成科学计数法
%f  %F 转换浮点数(小数部分自然截断)
%g  %G %e和%f %E和%F 的简写
%% 输出%


>格式化操作符辅助指令
符号 作用
* 定义宽度或者小数点精度
- 左对齐
+ 在整数前面显示加好+
<sp> 在整数前面显示空格
# 在八进制数前面显示零,在十六进制前面显示0x或者0X(取决于用的是x还是X)
0 显示的数字前面填充0,而不是默认的空格
% “%%”输出一个单一的"%"
(var) 映射变量(字典参数)
m,n m是显示的最小总宽度,n是小数点后的位数(如果可用的话)




Python支持2种格式的输入参数:元组和字典。


>字符串模板
from string import Template
s = Template("My name is ${name}")
s.substitute(name="zhangsan")




>原始字符串操作符 r/R
是为了对付那些在字符串中出现的特殊字符。




>字符串类型函数
输入
raw_input()


工厂函数
str()
unicode()

数值转换函数
chr() 参数:0-255
unichr() 参数:0-1114112


ord()


>字符串内建函数
string.capitalize()
string.title()


string.center(width)
string.count(str, beg = 0, end = len(string))


string.decode(encoding = 'UTF-8', errors = 'strict')
string.encode(encoding = 'UTF-8', errors = 'strict')

string.startswith(obj, beg = 0, end = len(string))
string.endswith(obj, beg = 0, end = len(string))


string.expandtabs(tabsize = 8)


string.find(str, beg = 0, end = len(string))
string.rfind(str, beg = 0, end = len(string))


string.index(str, beg = 0, end = len(string))
string.rindex(str, beg = 0, end = len(string))


string.isalnum()
string.isalpha()
string.isdecimal()
string.isdigit()
string.isnumeric()

string.islower()
string.isupper()


string.isspace()
string.istitle()


string.join(seq)

string.ljust(width)
string.rjust(width)

string.lower()
string.upper()


string.lstrip()


string.partition()
string.rpartition()


string.replace(str1, str2, num = string.count(str1))

string.strip()
string.rstrip()


string.split(str = "", num = string.count(str))
string.splitlines(num = string.count("\n"))


string.swapcase()
string.translate(str, del = "")
string.zfill(width)

>特殊字符串和控制字符
/X 八进制 十进制 十六进制 字符 说明
\0 000 0 0x00 NUL 空字符
\a 007 7 0x07 BEK 响玲字符
\b 010 8 0x08 BS 退格
\t 011 9 0x09 HT 横向制表符
\n 012 10 0x0A LF 换行
\v 013 11 0x0B VT 纵向制表符
\f 014 12 0x0C FF 换页
\r 015 13 0x0D CR 回车
\e 033 27 0x1B ESC 转义
\" 042 34 0x22 " 双引号
\' 047 39 0x27 ' 单引号
\\ 134 92 0x5C \ 反斜杠


控制字符的一个作用是用作字符串李的定界符。




>三引号:允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。




> Codecs(编码):定义了文本字符串跟二进制值之间的转换方式.
UTF-8编码(1-4个字节)方式中:ASCII字符的UTF-8编码跟ASCII编码完全相同。
UTF-16编码:固定用2个字节来编码,需要定义字节序是大端或小端。


当向一个文件写入字符串时,必须定义一个编码(encoing参数)用于把对应的 Unicode 内容转换成定义的编码格式。
相应的,当从文件读取数据时,必须“解码”该文件,使之成为相应的Unicode字符串对象。




>Unicode的使用规则
程序中出现字符串时一定加前缀u
不要用str()函数,用 unicode() 代替
不要用过时的 string 模块 -- 如果给它传递的是非ASCII字符,它会把一切搞砸
不到必要时不要在程序里编解码Unicode字符。只要在写入文件货数据库或者网络时,才调用ecode()函数;相应的,只在需要把数据都回来时才调用 decode() 函数。




================= 列表 ======================
>向列表中添加新列表
- 连接操作符+   创建了新的列表
- extend()函数 把新列表添加到原有列表里面


注意:append()方法是往列表里添加新元素


>可用于列表的标准类型函数
cmp()
len()
max()
min()
sorted() 返回排序后的列表(字典序)
reversed() 返回一个反响的 reversed 对象
enumerate() 获取索引和值
zip() 返回一个列表,每个元素都是一个元组(由参数中的每个列表相应索引组成)
sum()
list() 接受可迭代对象,浅拷贝数据。
tuple() 接受可迭代对象,浅拷贝数据。


>列表类型的内建函数
list.append(obj)
list.count(obj)
list.extend(seq)
list.index(obj, i = 0, j = len(list)
list.insert(index, obj)
list.pop(index = -1)
list.remove(obj)
list.reverse()
list.sort(func=None, key=None, reverse=False)




=============== 元组 ==========================
>所有函数返回的多对象(不包括有符号封装的)都是元组类型


>浅拷贝:新创建一个类型跟原对象一样,其内容是原来对象元素的引用。
换句话说:这个拷贝的对象本身是新的,但是他的内容不是。






================= 映射和集合类型 =====================


>字典的键必须是可哈希的:所有不可变类型都是可哈希的。
数字和字符串可以作为字典中的键,但是列表和其他字典不行。
注意:
值相等的数字表示相同的键。比如:整型数字1和浮点型数字1.0,表示相同的键。
有限制的元祖才能作为键:元祖中只包含数字和字符串这样的不可变参数。


>字典比较算法:首先是字典大小,然后是键,最后是值。


>工厂函数dict()
如果参数是可以迭代的,即:一个序列(列表,元组),或是一个迭代器,或是一个支持迭代的对象,那么每个可迭代的对象必须成对出现。在每个值对中,第一个元素是字典的键,第二个元素是字典的值。


>映射类型的相关函数
dict([container])
len(mapping)
hash(obj)
sorted(dict) 对dict的键进行排序,返回一个有序的迭代子


>映射类型的内建方法
dict.clear()
dict.copy()
dict.fromkeys(seq, val=None)
dict.get(key, default=None) 与[]操作符一样,但是不会产生异常。
dict.has_key(key)
dict.iter()
dict.pop(key [,default])
dict.setdefault(key, default=None) 如果key存在,返回dict[key];如果key不存在,设置dict[key]=default,然后返回default。
dict.update(dict2)


dict.keys() 返回所有key的列表
dict.values() 返回所有value的列表
dict.items() 返回所有(key, value)元组组成的列表

dict.iterkeys() 返回迭代对象
dict.itervalues()
dict.iteritems()




===================== 集合类型 set ==========================
>set/frozenset
由不同元素组成的集合。
集合对象时一组无序排列的可哈希的值。

>分类
set:可变集合
frozenset:不可变集合


>集合-标准类型操作符(适用于所有集合)
in/not in 成员关系
== 当且仅当其中一个集合中的每个成员同时也是另一个集合中的成员。
< <= > >= 子集、超集


>集合类型操作符 (适用于所有集合)
| 联合,等价方法union()
& 交集,等价方法intersection()
- 差补或相对补集,等价方法difference()
^ 对称差分/异或,等价方法symmetric_difference()
注意:
s op t :第一个s是可变集合,产生的新集合也是可变的。
t op s :第一个t是不可变集合,产生的新集合是不可变的。


>集合类型操作符 (仅适用于可变集合)
|= 添加新集合,等价函数:update()
&= 保留/交集更新,等价函数:intersection_update()
-= 差更新,等价函数:difference_update()
^= 对称差分更新,等价函数:symmetic_defference_update()


>标准类型内建函数
len()



>工厂函数
set([可迭代对象])
frozenset([可迭代对象])


>集合类型内建方法(适用于set, frozenset)
s.issubset(t) s是否是t的子集
s.issuperset(t) s是否是t的超集
s.union(t) 返回新集合:s与t的并集
s.intersection(t) 返回新集合:s与t的交集
s.difference(t) 返回新集合:该集合是s的成员,但不是t的成员
s.symmetric_difference(t) 返回新集合:该集合是s或t的成员,但不是s和t的共有成员。
s.copy() 返回新集合:他是集合s的浅拷贝。




>集合类型内建方法(仅适用于set可变集合)
s.update(t)
s.intersection_update(t)
s.difference_update(t)
s.symmeric_difference_update(t)
s.add()
s.remove()
s.discard()
s.pop()
s.clear()






========================= 条件和循环 ============
>if 多重判断条件:布尔操作符-and, or, not


>条件表达式(三元操作符) X if C else Y


>while循环是条件性,for循环是迭代性 


>for语句:
1.可以遍历序列成员,可以用在 列表解析 和 生成器表达式 中。
2.可以遍历迭代器对象,它会自动调用迭代器的next()方法,
捕获 StopIteration 异常并结束循环(所有这一切都是在内部发生的)。
与传统语言中的for语句不通,Python 的 for 更像是 shell 或脚本语言中的 foreach 循环。


>迭代序列一个的3种基本方法
1.通过序列项迭代
nameList = ['a', 'b', 'c']
for item in nameList:
print item

2.通过序列索引迭代
nameList = ['a', 'b', 'c']
for index in range(len(nameList)):
print nameList[index]

3.使用项和索引迭代
nameList = ['a', 'b', 'c']
for index, item in enumerate(nameList):
print nameList[index]


>xrange()只能用在 for 循环中。


>与序列相关的内建函数
sorted() 返回列表
reversed() 返回迭代器
enumerate() 返回迭代器
zip() 返回列表


>循环中使用else语句:只在循环正常结束后执行(没有执行break语句)。


>迭代器:是一个支持迭代的对象(有f()方法)
限制:不能向后移动,不能回到开始,不能复制一个迭代器。


>序列类型支持迭代,自动生成迭代器
for i in seq:
do_something(i)

实际上是这样工作的

fetch = iter(seq)
while True:
try:
i = fetch.next()
except StopIterration:
break
do_something(i)

注意:一个序列的迭代器只是记录你当前到达第几个元素,所以如果在迭代时改变了元素,更新会立即反映到所迭代的条目上。


>字典类型支持迭代,自动生成迭代器会遍历它的键
另外,字典还引进了三个内建字典方法来定义迭代:
dict.iterkeys()
dict.itervalues()
dict.iteritems()

>文件对象也支持迭代,自动生成的迭代器会自动调用readline()方法。


>创建迭代器
iter(obj) 如果obj是一个序列类型对象,根据索引从0一直迭代到结束。
iter(func, sentinel)重复调用func,直到迭代器的下一个值等于sentinel。

>列表解析:动态的创建列表
结合了列表的方括符和for循环,在逻辑上描述要创建的列表的内容。
语法:
[expr for iter_var in iterable]
[expr for iter_var in iterable if cond_expr]


>生成器:是一个特定的函数,允许你返回一直值,然后“暂停”代码的执行,稍候恢复。


>生成器表达式:(expr for iter_var in iterable if cond_expr)
 并不真正创建数字列表,而是返回一个生成器,这个生成器在每次计算出一个条目后,把这个条目“产生”(yield)出来。
eg:获取一个文件最大行的长度
return max(len(line.strip()) for line in open("test.txt", "r")
解释:max函数的参数是一个生成器,生成器也是一个可迭代对象,正好max()函数需要可迭代对象。






========================= 文件和输入输出 =========================
>文件对象 不仅可以用来访问普通的磁盘文件,而且也可以访问其他任何类型抽象层面上的“文件”。
一旦设置了合适的“钩子”,你就可以访问具有文件类型接口的其他对象,就好像访问的是普通文件一样。




>文件对象 file_object = open(file_name, access_mode = "r", buffering = -1)
file_name 绝对或相对路径
access_mode r,w,a,U,+,b
r,U-文件必须已经存在, w-文件若存在则首先清空,然后重新创建
a-如果文件不存在将自动创建,类似w模式;如果文件已经存在,所有写入的数据都
 将追加到文件末尾,即使你seek到了其他地方
U - 代表通用换行符支持
+ 代表可读可写
b - 二进制模式访问。对于所有POSIX兼容的unix系统,'b'是可有可无的,因为它们
   把所有的文件都当作二进制文件,包括文本文件。
buffering 指示访问文件所采用的缓冲方式
0 - 不缓冲
1 - 只缓冲一行数据
大于1的值 - 使用给定值作为缓冲区大小
不提供该参数或给定负值 - 使用系统默认缓冲机制(即:对任何类电报机tty设备
使用行缓冲,其他设备使用正常缓冲)


>通用换行符支持(UNS)
- 编译 Python时,默认打开。如果不需要,在运行 configure 脚本时,使用 --without-universal-newlines 开关关闭。
- UNS只用于读取文本文件,没有对应的处理文件输出的方法。
- 当使用U标志打开文件时,所有的行分隔符(或行结束符)通过Python的输入方法(例如read*())返回时,都会被
替换为换行符NEWLINE(\n)。


>OS模块
操作系统之间的差异之一是所支持的行分隔符不同。
POSIX(Unix系列或Mac OS X)系统上,行分隔符是 换行符NEWLINE(\n)字符。
旧的MacOS上,是 RETURN(\r)。
DOS和Windows系统上,是结合了两者(\r\n)。
另一个不同是路径分隔符:
POSIX:"/"
旧版本MacOS:":"
DOS 和 Windows: "\"


解决:OS模块属性
linesep 用于在文件中分隔行的字符串
sep 用来分隔文件路径名的字符串
pathsep 用于分隔文件路径的字符串
curdir 当前工作目录的字符串名称
pardir (当前工作目录的)符目录的字符串名称


>文件对象的内建方法
file.close() 关闭
file.fileno() 返回文件描述符,整数值
file.flush()
file.isattry() file是否是一个类tty设备
file.next() 读取文件下一行,没有时触发 StopIteration 异常
file.read(size=-1) 读取size个字节。未给定size或给定负值时,读取剩余所有字节
file.readline(size=-1) 读取一行(包括行结束符),或返回最大size个字符
file.readlines(sizhint=0) 读取所有行并作为一个列表返回(包含所有的行结束符)
如果给定sizhint且大于0,那么返回总和大约为sizhint字节的行
file.xreadlines() 用于迭代,可以替换readlines()的一个更高效方法
file.seek(off, whence=0) 从 whence(0-文件开始,1-当前位置,2-文件末尾)便宜off字节
file.tell()
file.truncate(size=file.tell())
file.write(str)
file.writelines(seq) seq-返回字符串的可迭代对象


>文件内建属性
file.closed 是否已经被关闭
file.encoding 文件所用的编码
file.mode
file.name
file.newlines 未读取到行分隔符时为None
只有一种行分隔符时为一个字符串
当文件有多种类型的行分隔符是,则为一个包含所有当前所遇到的行分隔符的列表
file.softspace 0 - 表示在输出一数据后,要加上一个空格符;1 - 表示不加。


>标准文件
标准输入 - 键盘
标准输出 - 到显示器的缓冲输出
标准错误 - 到显示器的非缓冲输出

任一个程序默认打开这3个文件,导入  sys 模块后,即可访问这3个文件句柄:sys.stdin, sys.stdout, sys.stderr




>命令行参数:调用程序时,除了程序名以外的其他参数。通过 sys.argv 属性来访问命令行参数。
sys.argv[0] 永远是程序的名称。




>os 模块:是Python 访问操作系统功能的主要接口。
该模块除了对进程和进程运行环境进行管理外,还负责处理大部分的文件系统操作。
os 模块实际上只是真正加载的模块的前段,而真正的那个“模块”明显要依赖于具体的操作系统。
这个“真正”的模块可能是以下几种之一:
posix(适用于 Unix 操作系统)
nt(Win32)
mac(旧版本的MacOS)
dos(DOS)
os2(OS/2)


>os 模块的文件/目录访问函数
文件处理函数 描述
mkfifo()/mknod() 创建命名管道/创建文件系统节点
remove()/unlink() 删除文件
rename()/renames() 重命名文件
*stat() 返回文件信息
symlink() 创建符号链接
utime() 更新时间戳
tmpfile() 创建并打开("w+b")一个新的临时文件
walk() 生成一个目录树下的所有文件名

目录/文件夹函数 描述
chdir()/fchdir() 改变当前工作目录/通过一个文件描述符改变当前工作目录
chroot() 改变当前进程的跟目录
listdir() 列出指定目录的文件
getcwd()/getcwdu() 返回当前工作目录/功能相同,但是返回一个Unicode对象
mkdir()/makedirs() 创建目录/创建多层目录
rmdir()/removedirs() 删除目录/删除多层目录

访问权限函数 描述
access() 检验权限模式
chmod() 改变权限模式
chown()/lchown() 改变owner和group ID/功能相同,但不会跟踪链接。
umask() 设置默认权限模式


文件描述符操作函数 描述
open() 底层的操作系统open
read()/write() 根据文件描述符读取/写入数据
dup()/dup2() 复制文件描述符号/功能相同,但是是复制到另一个文件描述符设备号
makedev() 从major和minor设备号创建一个原始设备号
major()/minor() 从原始设备号获得mamor/minor设备号
>os.path 模块:路径名访问函数
分隔 描述
basename() 去掉目录路径,返回文件名
dirname() 去掉文件名,返回目录路径
join() 将分离的各部分组成一个路径名
split() 返回(dirname(), basename())元组
splitdrive() 返回(drivename, pathname)元组
splitext() 返回(filename, extension)元组


信息 描述
getatime() 获取最近访问时间
getctime() 获取文件创建时间
getmtime() 返回最近文件修改时间
getsize() 返回文件字节大小


查询 描述
exists() 指定路径(文件或目录)是否存在
isabs() 指定路径是否为绝对路径
isdir() 指定路径是否存在且为一个目录
isfile() 指定路径是否存在且为一个文件
islink() 指定路径是否存在且为一个符号链接
ismount() 指定路径是否存在且为一个挂载点
samefile() 两个路径名是否指向同一个文件




>永久性存储模块:
介于磁盘文件存储和完整的关系数据库存储系统之间的存储需求。


> marshal和pickle模块
用来转换并存储Python对象,该过程将比基本类型复杂的对象转换成一个二进制数据集合,这样就
可以把数据集合保存起来或通过网络发送,然后再重新把数据集合恢复成原来的对象格式。
这个过程也成为:数据的扁平化,数据的序列化或者数据的顺序化。


marshal 只能处理简单的 Python 对象(数字,序列,映射,以及代码对象)
pickle 还可以处理递归对象,被不同地方多次引用的对象,以及用户定义的类和实例。


>DBM风格的模块
提供一个类似字典和文件的对象,可以完成字符串的永久性存储。
Python 提供了DBM的多种实现:dbhash/baddb, dbm, gdbm, dumbdbm


>shelve模块
使用cPickle来完成对Python对象的储存转换,然后使用anydbm模块寻找合适的DBM模块,完成 Python对象的永久性存储。






================================= 错误和异常 =================================
>语法
try:
try_suite
except Exception1[, reason1]:
except_suite1
except Exception2[, reason2]:
except_suite2
except (Exception3, Exception4)[, reason3_4]
except_suite3_4
else:
pass #try中没有任何异常发生时执行else
finally:
pass #无论try中是否发生异常,finally都会执行

异常参数reasong将会是一个包含来自导致异常的代码的诊断信息的类的实例。


>try-finally语句
try:
try_suite
finally:
finally_suite
这个结构不是用来捕获异常的,常常用来维持一致的行为而无论异常是否发生。
当try中产生一个异常时,会立即跳转到finally语句段,当finally中的所有代码
都执行完毕后,会继续向上一层引发异常。


>捕获所有异常
try:
pass
except BaseException, e:
pass




>封装内建函数
def safe_float(obj):
try:
retval = float(obj)
except ValueError:
retval = "could not convert non-number to float"
except TypeError:
retval = "argument must be a string"
return retval




>with语句:仅能工作于支持上下文管理协议的对象。


语法:
with context_expr [as var]:
with_suite


try-except和try-finally的一种特定的配合用法是保证共享的资源的唯一分配,并在任务结束的时候释放它。
比如文件(数据,日志,数据库等),线程资源,简单同步,数据库链接等。
with语句的目标就是应用在这种场景。


支持上下文管理协议的有:
file
decimal.Context
thread.LockType
threading.Lock
threading.RLock
threading.Condition
threading.Semaphore
threading.BoundedSemaphore


例如:
with open("test.txt", "r") as f:
for line in f:
pass




支持上下文管理协议的类型中的几个方法:
__context__()
__enter__()
__exit__()




>raise 语句:引发异常
raise [SomeException [, args [, traceback]]]


SomeException:触发异常的名字,是一个字符串,类,或者实例。
args:传给异常,可以是一个单独的对象,也可以是一个对象的元组。
traceback:异常触发时,新生成的一个用于异常-正常化的追踪对象。




>assert 语句:断言
assert expression[, arguments]


断言成哦功能不采取任何措施;否则触发 AssertionError 的异常。


断言类似于下面的函数实现:
def assert(expr, args=None):
if __debug__ and not expr:
raise AssertionError, args


>Python内建的标准异常
BaseException 所有异常的基类

SystemExit Python解释器请求退出
KeyboardInterrupt 用户终端执行(ctrl+c)
Exception 常规错误的基类

StopInteration 迭代器没有更多的值
GeneratorExit 生成器发生异常来退出

StandardError 所有的内建标准异常的基类
ArithmeticError 所有数值计算错误的基类
FloatingPointError 浮点计算错误
OverflowError 数值运算超过最大限制
ZeroDivisionError 除(或取模)零,(所有数据类型)
AssertionError 断言语句失败
AttributeError 对象没有这个属性
EOFError 没有内建输入,到达EOF标记
EnvironmentError 操作系统错误的基类
IOError 输入/输出操作失败
OSError 操作系统错误
WindowsError Windows系统调用失败
ImportError 导入模块/对象失败
LookupError 无效数据查询的基类
IndexError 序列中没有此索引
KeyError 映射中没有这个键
MemoryError 内存溢出错误(对于python解释器不是致命的)
NameError 未声明/初始化对象(没有属性)
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用视图访问已经垃圾回收了的对象
RuntimeError 一般的运行时错误
NotImplementError 尚未实现的方法
SyntaxError Python语法错误
IndentationError 缩进错误
TabError Tab和空格混用
SystemError 一般的解释器系统错误
TypeError 对类型无效的操作
ValueError 传入无效的参数
UnicodeError Unicode相关的错误
UnicodeDecodeError Unicode解码时的错误
UnicodeEncodeError Unicode编码时错误
UnicodeTranslateError Unicode转换时错误

Warning 警告的基类
DeprecationWarning 关于被弃用的特征的警告
FutureWarning 关于构造将来语义会有改变的警告
OverflowWarning 旧的关于自动提升为长整型的警告
PendingDeprecationWarning 关于特性将会被放弃的警告
RuntimeWarning 可疑的运行时行为
SyntaxWarning 可疑的语法的警告
UserWarning 用户代码生成的警告


>异常继承关系
-BaseException
|_KeyboardInterrupt
|_SystemExit
|_Exception
|_所有其他内建异常




================== 函数编程 =======================
>Python中函数调用的完整语法:
func(positional_args, keyword_args, *tuple_group_args, **dict_group_args)


>内嵌/内部函数
def foo():
def bar():
print "bar() called"
print "foo() called"
bar()


>函数(与方法)装饰器
@decorator(dec_opt_args)
def func2Bdecorated(func_opt_args):
pass



装饰器实际上就是函数。它们接受函数对象进行包装,然后返回修改后的函数对象。
装饰器可以用来:
引入日志
增加计时逻辑来检测性能
给函数加入事物的能力


>装饰器 demo
#!/usr/bin/env python

from time import ctime, sleep

# tsfunc()函数是一个显示何时调用函数的时间戳的装饰器
def tsfunc(func):
def wrapperFunc():
print '[%s] %s() called' % (ctime(), func.__name__)
return func()

# 返回一个“包装了”的函数
return wrapperFunc

@tsfunc
def foo():
pass

# 到这里,相当于:foo = tsfunc(foo)
# 调用foo()函数实际上市调用装饰器包装后的函数wrapperFunc()

foo()
sleep(4)
for i in r


>传递函数
函数也是一个对象,与其他python对象一样可以被引用,被传递。
特殊:函数对象可以被调用。

demo:
#!/usr/bin/env python


def convert(func, seq):
return [func(item) for item in seq]

myseq = (123, 45.67, -6.2e9, 999999L)
print convert(int, myseq)
print convert(long, myseq)
print convert(float, myseq)

>形式参数
位置参数:所有的位置参数必须出现在任何一个默认参数之前。
默认参数
关键字参数

>可变长度的参数
由于函数调用提供了关键字和非关键字两种参数类型,Python用两种方法来支持变长参数。
1.非关键字可变长参数(元祖)
当函数被调用时,所有的形参(必须的和默认的)都将赋值给在函数声明中相对应的局部变量。
剩下的非关键字参数按顺序插入到一个元祖中。
可变长的参数元祖必须在位置和默认参数之后。

def func_name([formal_args,] *vargs_tuple)
func_body_suite


元祖vargs_tuple 保存了所有传递给函数的除了匹配到formal_args之外的参数。


2.关键字变量参数(字典)
有不定数目或者额外集合的关键字的情况中,参数被放入一个字典中。
字典的键位参数名,字典的值为参数值。
关键字变量参数应该为函数定义的最后一个参数。

def func_name([formal_args,] [*vargs_tuple,] **vargs_dict)
func_body_suite


>示例:
函数定义
def func(arg1, arg2, arg3="hello", *argst, **argsd)
pass

调用
1.
func(1,2,3,4,5,6,name="zhangsan",age=30)
那么:arg1 = 1
arg2 = 2
arg3 = 3
argst元祖:(4,5,6)
argsd字典:{"name":"zhangsan", "age":30}


2.
func(1,2,3,*(4,5,6), **{"name":"zhangsan", "age":30})
那么:arg1 = 1
arg2 = 2
arg3 = 3
argst元祖:(4,5,6)
argsd字典:{"name":"zhangsan", "age":30}

3.
aTuple = (5,6,7)
aDict = {"name":"zhangsan", "age":30}
func(1,2,3, 4, sex="male", *aTuple, **aDict)
那么:arg1 = 1
arg2 = 2
arg3 = 3
argst元祖:(4,5,6,7)
argsd字典:{"name":"zhangsan", "age":30, "sex":"male"}
传递的实参中元祖和字典仅仅是被调函数中最终接收的元祖和字典的子集。





>匿名函数与lambda
lambda [arg1[, arg2, ..., argN]]:expression
返回可调用的函数对象。


实力:
test = lambda x, y=2: x+y
test(1) ==>结果:3




>内建函数
apply(func[, nkw][, kw]) 用可选的参数来调用func(废弃不用)
filter(func, seq) 使用一个布尔函数func来迭代遍历seq中每个元素,返回一个使func返回值
为true的元素的序列
map(func, seq1[, seq2...]) 将函数func作用于给定序列的每个元素,并用一个列表来提供返回值。
reduce(func, seq[, init]) 将二元函数func作用于seq序列中的元素,每次携带一对(之前的结果和下一个序列元素)


示例:
filter(lambda x: x-1, [1,2,3]) 返回结果:[2,3]
map(lambda x: x-1, [1,2,3]) 返回结果:[0,1,2]
map(lambda x,y:x+y, [1,2,3], [7,8,9]) 返回结果:[8,10,12]
map(None, [1,2,3], [7,8,9]) 返回结果:[(1,7),(2,8),(3,9)]
reduce(lambda x, y:x+y, (1,2,3)) 返回结果:6


>偏函数 PFA
将函数式编程的概念和默认参数以及可变参数结合在一起。
相当于把一些参数固定起来,不需要每次调用时都传递那些固定的参数。


>>> from operator import add
>>> from functools import partial
>>> add1 = partial(add, 1)
>>> add1(10)
11


>>> add2 = partial(add, 1, 2)
>>> add2
<functools.partial object at 0x12345678>
>>> add2()
3


在GUI编程中使用:
from functools import partial
import Tkinter

root = Tkinter.Tk()
MyButton = partial(Tkinter.Button, root, fg="white", bg="blue")
b1 = MyButton(text="Button 1")


>变量作用域
局部变量:定义在函数内部。
全局变量:定义在模块最高级别。

当搜索一个标识符时,Python先从局部作用域开始找,如果找不到,
然后在全局作用域开始找。如果也找不到,抛出NameError。




>闭包 
Python支持静态嵌套域(内部函数)。
如果在一个内部函数里,对外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
定义在外部函数内的,但是被内部函数引用或使用的变量称为自由变量。
闭包将内部函数自己的代码和作用域以及外部函数的作用域结合起来。


闭包就是函数,但是能够携带一些额外的作用域。


实例:
def counter(start_at=0):
count = [start_at]

def incr():
count[0] += 1
return count[0]

return incr
内部函数incr(),通过使用变量count,变成一个闭包,携带了整个counter()作用域。

单元(cell):是在函数作用域结束后使函数中被闭包引用的自由变量保持存活的一个空间。


>变量作用域和名字空间
从函数内部,局部作用域包围了局部名字空间,第一个搜寻名字的地方。
如果名字存在的话,将会跳过检查全局作用域(全局和内建的名字空间)。




>递归
def factorial(n):
if 0 == n or 1 == n:
return 1
else:
return n * factorial(n-1)




>生成器:挂起返回出中间值并多次继续的协同程序被成为生成器。
从语法上讲,生成器就是一个带yield语句的函数。


与迭代器比较:
迭代器:是一个支持迭代的对象(有next()方法)。限制:不能向后移动,不能回到开始,不能复制一个迭代器。
生成器的动机之一就是像迭代器一样以某种方式生成下一个值并返回。


当一个生成器对象结束没有更多的值返回时,一个StopIteration异常就会抛出。


示例:
def simpleGen():
yiled 1
yiled "hello"


>>> sG = simpleGen()
>>> sG.next()
1
>>> sG.next()
hello
>>> sG.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration



>加强的生成器特性:
next() 获得下一个生成的值
send() 将值回送给生成器
close() 要求生成器退出


示例:
def counter(start_at = 0):
count = start_at
while True:
# val用来接收用户回送给生成器的值
val = (yield count)
if val is not None:
count = val
else:
count += 1




>>> c = counter(5)
>>> c.next()
5
>>> c.next()
6
>>> c.next()
7
>>> c.send(10)
10
>>> c.next()
11
>>> c.next()
12
>>> c.next()
13




=============== 模块 ======================
>模块
模块用来组织python代码,包用来组织模块。
模块是按照逻辑来组织python代码,文件是物理层上组织模块的方法。

>搜索路径
模块的导入需要一个叫做“路径搜索”的过程。
即在文件系统“预定义区域”中查找 modulename.py这个而文件。

1.环境变量 PYTHONPATH
2.变量 sys.path


可以修改环境变量或者修改sys.path来添加模块的搜索路径。

sys.modules可以找到当前已经导入了哪些模块以及来自什么地方。


>名称空间:是名称(标识符)到对象的映射。
在程序执行期间有两个或三个活动的名称空间:
局部名称空间
全局名称空间
内建名称空间。
局部名称空间在执行期间是不断变化的,所以说有“两个或三个”。


Python解释器首先加载内建名称空间,由__buildins__模块中的名字构成。
随后加载执行模块的全局名称空间,它会在模块开始执行后变为活动名称空间。
如果在执行期间调用了一个函数,那么将创建出局部名称空间。


>名称空间域变量作用域的比较
作用域是纯粹意义上的名字和对象之间的映射关系。
而作用域还指出了从用户代码的哪些物理位置可以访问到这些名字。

名称空间是独立的(是否存在?),而作用域是“纵向”的(能否看得见?)。
例如:在一个函数内,可以访问局部名称空间中的名字,也可以访问全局名称空间和内建名称空间中的名字。

>无限制的名称空间
你可以在任何需要放置数据的地方获得一个名称空间。例如:
def foo():
pass
foo.__doc__ = "just test"
foo.version = 0.2
函数对象foo只是被用作一个名称空间。

class MyClass(Object):
pass
myObj = MyClass()
myObj.x = 100
myObj.version = 0.1
类实例对象myObj只是被用作一个名称空间。

>导入模块
# 模块名就是一个名称空间
import Tkinter

# 把变量导入到当前的名称空间
from Tkinter import Tk, Frame, Button
from Tkinter import Entry, Canvas, Text

import Tkinter as tk

from cgi import FieldStorage as form

模块在第一次被导入时被加载。

模块被首次加载时,会导致这个模块被“执行”。也就是被导入模块的顶层代码将
直接被执行,通常包括:设定全局变量以及类和函数的声明。如果有检查__name__
的操作,也会被执行。


>模块内建函数
__import__() 提供这个函数时为了让有特殊需求的用户覆盖它,实现自定义的导入算法。
例如:import sys 相当于:sys = __import__('sys')
globals() 返回调用者全局名称空间的字典
locals() 返回调用者局部名称空间的字典
在全局名称空间下,globals()和locals()返回相同的字典,因为这时的局部名称空间就是全局空间。
reload(module)重新导入一个已经导入的模块




>包:是一个有层次的文件目录结构
每个目录下都需要一个 __init__.py 文件,其中有一个 __all__ 变量,该变量定义了执行:
from package.module import *
这样的语句时,应该导入的模块的名字。
例如:存在这样的文件目录层次 Phone/Mobile/Anolog.py
可以这样导入:
from Phone import Mobile
Mobile.Analog.dial("12345678")

from Phone.Mobile import Analog
Analog.dial("12345678")

from PHone.Mobile.Analog import dial
dial("12345678")


>import 默认执行的是绝对导入
相对导入只能使用 from-import 语句。例如:
from Phone.Mobile.Analog import dial
from .Analog import dial
from ..common_util import setup
from ..Fax import G3.dial




>自动导入的模块
当 Python 解释器在标准模式下启动时,一些模块会被解释器自动导入,用于系统相关操作。
查看:sys.modules


>阻止属性导入
如果不想让模块的某个属性被 "from module import *"导入,可以给不想导入的属性名称加上一个下划线(_)。




>源代码编码
从 2.3 开始,Python 的模块文件开始支持除 7 位 ASCII 码之外的其他编码,默认仍是 ASCII 码。
指定文件编码:
#!/usr/bin/env python 
# -*- coding:UTF-8 -*-




======================= 面向对象编程 ===============================
> 类
最简单的类,仅仅用作名称空间。


>继承
如果需要,每个子类最好定义它自己的构造器,不然,基类的构造器就会被调用。
如果子类重写基类的构造器,基类的构造器就不会被自动调用了--这样基类的构造器
就必须显示写出来才会被执行。而且要显示的传递self实例对象给基类构造器。




>OOD: 面向对象设计
>OOP: 面向对象编程


>类的数据属性
属于类的变量,与所属的类对象帮顶,不依赖于任何类实例。类似于java里的static 静态成员变量。
通常仅用来跟踪与类相关的值。
class C(object):
foo = 100


类属性可以通过类访问,也可以通过实例来访问,但是不能通过实例来修改类属性,那将会定义一个实例属性(屏蔽掉类属性)。


>类的方法属性
查看一个类的所有属性:
1.内建函数dir()
2.使用类的字典属性_dict__。

>类的特殊属性
对于任何类C,特殊属性有:
C.__name__ 类C的名字(字符串)
C.__doc__ 类C的文档字符串
C.__bases__ 类C的所有父类构成的元祖
C.__dict__ 类C的属性
C.__module__ 类C定义所在的模块
C.__class__ 实例C对应的类

>类和类型的统一
在Python2.2之前的版本中:
类是类对象,实例是实例对象。这两个对象之间没有任何关系,除了实例对象的__class__属性引用了被实例化以得到该实例的类。
当你定义一个新的类时,你并没有创建一个新的类型,而是仅仅一个类对象。
int()还不具备工厂功能...,它还仅仅是一个通常的内建函数。
例如:
>>> 定义一个类MyClass
>>> type(MyClass)
<type 'class'> #一个类对象
>>> mc = MyClass()
>>> type(mc)
<type 'instance'> #一个实例对象

>>> type(0)
<type 'int'> #一个type类型对象

>>> type(int)
<type 'buildin_function_or_method'>

Python2.2以及后续版本中:
由于类型和类的统一,一个类就是一个类型(也是一个对象),这个类型对象所属的类就是类型type。
定义一个类就是定义一个新的类型。
任何类(或者说类型)的实例都是这种新建类型的实例。
>>> 定义类MyClass
>>> type(MyClass)
<type 'type'> #一个类型
>>> mc = MyClass()
>>> type(mc)
<class '__main__.MyClass'>

>>> type(0)
<type 'int'> #一个类型对象,指出参数0是一个int类型对象
>>> type(int)
<type 'type'> #一个类型对象,指出参数int是一个类型对象(type)。


>特殊方法
__init__()方法
当类被调用时,实例化的第一步是创建实例对象,第二步是调用__init__()方法,如果存在的话。
实例对象传递给__init__()的第一个参数self。
类调用时的参数传递给__init__()的其他参数。

__new__()静态方法
用于对内建类型进行派生时。
会自动调用父类的__new__()方法。
必须返回一个合法的实例。

__del__()方法
一个实例对象的所有引用都被清除掉之后才会执行。
提供了一个途径,在实例释放前做一些特殊处理。




>实例属性
设置实例属性可以在实例创建后任意时间进行。
一般都实在__init__()函数中设置实例属性。


查看方法:
1.dir(obj) 包括:类属性,特殊属性
2.obj.__dict__ 仅仅包含实例属性


特殊属性
obj.__class__ 实例化obj的类
obj.__dict__ obj的属性




类和实例都是名称空间。类是类属性的名称空间,实例则是实例属性的名称空间。





>绑定
方法是类内部定义的函数,是类属性而不是实例属性。
Python 严格要求,没有实例,方法是不能被调用的。当存在一个实例时,方法才被认为是绑定到那个实例。
第一个参数self用来代表绑定到哪个实例。


>静态方法和类方法
一般的方法需要一个实例self作为第一个参数,而且对于绑定的方法调用来说,self是自动传递的。
而类方法需要类,而不是一个实例作为第一个参数,它是由解释器传给方法的。


修饰符
@staticmethod
@classmethod


静态方法和类方法都可以通过类或者实例来调用。
示例:
静态方法
class TestStaticMethod(object):
@staticmethod
def foo():
print "calling static method foo()"


>>> sMethod = TestStaticMethod()
>>> TestStaticMethod.foo()
calling static method foo()
>>> sMethod.foo()
calling static method foo()


类方法
class TestClassMethod(object):
@classmethod
def foo(cls):
print "calling class method foo()"
print "foo() is part of class: ", cls.__name__

>>> cMethod = TestClassMethod()
>>> TestClassMethod.foo()
calling class method foo()
foo() is part of class:  TestClassMethod
>>> cMethod.foo()
calling class method foo()
foo() is part of class:  TestClassMethod




>通过继承覆盖方法
class P(object):
def foo(self):
print "Hi, I am P-foo()"


p = P()
p.foo()
Hi, I am P-foo()
 
#继承
class C(P):
def foo(self):
print "Hi, I an C-foo()"


c = C()
c.foo()
Hi, I an C-foo() #调用的是覆写的方法



#可以调用未绑定的方法,传递子类对象进去
P.foo(c)
Hi, I am P-foo()



#典型的是在子类的覆写方法中调用父类中的方法
class C(P):
def foo(self):
P.foo(self) #调用未绑定方法
# super(C, self).foo() # 效果更好,自动找出父类。


print "Hi, I am in C-foo()"



>从标准类型派生
1.不可变类型
class RoundFloat(float):
def __new__(cls, val):
return float.__new__(cls, round(val, 2))
# return super(RoundFloat, cls).__new__(cls, round(val , 2))


理解:cls变量就是 RoundFloat 类对象。




2.可变类型
class SortedKeyDict(dict):
def keys(self):
return sorted(super(SortedKeyDict, self).keys())


>多重继承
方法解释顺序(MRO)
class.__mro__ 属性查看属性搜索顺序。


1.经典类-采用深度优先算法。
2.新式类-如果仍采用深度优先,会形成菱形(所有类的最终祖先都是object类),所以采用广度优先算法。




>类、实例和其他对象的内建函数
issubclass(sub, supper) 是否是(非严格)子类
issubclass(sub, supper_class_tuple) 是否是元组中任一个类的(非严格)子类

isinstance(obj1, Class) 是否是一个类或其子类的一个实例
isinstance(obj1, Class_tuple) 是否是元组中任一个类或其子类的一个实例

hasattr()
getattr()
setattr()
delattr()




dir(class) 显示类以及所有基类的 __dict__ 中的内容。
dir(obj) 显示实例变量,还有在实例所在的类以及所有基类中定义的方法和类属性。
dir(module) 显示模块的 __dict__ 中的内容。
dir() 显示调用者的局部变量


super(type[, obj]) 帮助程序员找出父类(方便调用相关的属性)
obj如果是一个类或类型,obj应该是type的非严格子类。
obj如果是一个实例,obj应该是type或type子类的一个实例。


vars(obj) obj必须有一个__dict__属性。返回一个字典,包含obj.__dict__中的属性和值。




>特殊方法定制类
基本定制型
C.__init__(self[, arg1, ...]) 构造器
C.__new__(cls[, arg1, ...]) 构造器,通常用在设置不变数据类型的子类
C.__del__(self) 解构器
C.__str__(self) 可打印的字符输出;内建str()及print语句
C.__repr__(self) 运行时的字符串输出;内建repr()和``操作符
C.__unicode__(self) Unicode 字符串输出;内建unicode()
C.__call__(self, *args) 表示可调用的实例
C.__nonzero__(self) 为object定义 False 值;内建bool()
C.__len__(self) "长度"(可用于类);内建len()


对象值比较
C.__cmp__(self, obj) 对象比较;内建cmp()
C.__lt__(self, obj) 小于或等于
C.__gt__(self, obj) 大于或等于
C.__eq__(self, obj) 等于


属性
C.__getattr__(self, attr) 获取属性;内建getattr();仅当属性没有找到时调用
C.__setattr__(self, attr, val) 设置属性
C.__delattr__(self, attr) 删除属性
C.__getattribute__(self, attr) 获取属性;内建getattr();总是被调用
C.__get__(self, attr) (描述符)获取属性
C.__set__(self, attr, val) (描述符)设置属性
C.__delete__(self, attr) (描述符)删除属性




定制类/模拟类型
数值类型:二进制操作符
C.__*add__(self, obj)
C.__*sub__(self, obj)
C.__*mul__(self, obj)
C.__*div__(self, obj)
C.__*truediv__(self, obj) 真除
C.__*floordir__(self, obj) 地板除
C.__*mod__(self, obj) 取模/取余
C.__*divmod__(self, obj) 除和取模
C.__*pow__(self, obj[, mod]) 乘幂
C.__*lshift__(self, obj) 左移
C.__*rshift__(self, obj) 右移
C.__*and__(self, obj) 按位与
C.__*or__(self, obj) 按位或
C.__*xor__(self, obj) 按位异或


数值类型:一员操作符
C.__neg__(self) 一元负
C.__pos__(self) 一元正
C.__abs__(self) 绝对值
C.__invert__(self) 按位求反


数值类型:数值转换
C.__complex__(self, com) 转为复数
C.__int__(self) 转为int
C.__long__(self) 转为long
C.__float__(self) 转为float


数值类型:基本表示法(String)
C.__oct__(self) 八进制表示
C.__hex__(self) 十六进制表示

数值类型:数值压缩
C.__coerce__(self, num) 压缩成同样的数值类型
C.__index__(self) 在有必要时,压缩可选的数值类型为整型(比如:用于切片索引等)


序列类型
C.__len__(self) 序列中的数目
C.__getitem__(self, ind) 得到单个序列元素
C.__setitem__(self, ind, val) 设置单个序列元素
C.__delitem__(self, ind) 删除单个序列元素


C.__getslice__(self,ind1,ind2) 得到序列片段
C.__setslice__(self,i1,i2,val) 设置序列片段
C.__delslice__(self,ind1,ind2) 删除序列片段
C.__contains__(self, val) 测试序列成员;内建in关键字

C.__*add__(self, obj) 串联;+操作符
C.__*mul__(self, obj) 重复;×操作符


C.__iter__(self) 创建迭代类;内建 iter()

映射类型
C.__len__(self) mapping中的项的数目
C.__hash__(self) 散列的函数值
C.__getitem__(self, key) 得到给定 key 的 value
C.__setitem__(self, key, val) 设置给定 key 的 value
C.__delitem__(self, key) 删除给定 key 的 value
C.__missing__(self, key) 给定 key 如果不存在字典中,则提供一个默认值




定制实例:
#!/usr/bin/env pthon


class RoundFloatManual(object):
def __init__(self, val):
assert isinstance(val, float)
self.value= round(val, 1)

def __str__(self):
return "%.2f" % self.value

__repr__ = __str__


在类的外部定义一个新对象时,一般直接使用类名来调用。
在类的内部定义一个新对象时,一般使用self.__class__()来调用。




重载一个 __i*__()方法的唯一秘密是它必须返回self。

class NumStr(object):
def __init__(self, num=0, string=''):
self.__num = num
self.__string = string

def __str__(self):
return "[%d::%r]" % (self.__num, self.__string)

__repr__ = __str__

def __add__(self, other):
if isinstance(other, NumStr):
return self.__class__(self.__num + other.__num, \
self.__string + other.__string)
else:
raise TypeError, "Illegla argument"

def __mul__(self, num):
if isinstance(num, int):
return self.__class(self.__num * num, self.__string * num)
else:
raise TypeError, "Illegal argument"

def __nonzero__(self):
return self.__num or len(self.__string)

def __norm_cval(self, cmpres):
return cmp(cmpres, 0)

def __cmp__(self, other):
return self.__norm_cval(cmp(self.__num, other.__num)) + \
self.__norm_cval(cmp(self.__string, other.__string))

> 包装和授权
包装一个类型通常是对已存在的类型的一些定制。包括:新建,修改或删除原有的功能。
授权是包装的一个特性,即是:所有更新的功能都是由新类的某部分来处理,但已存在
的功能就授权给对象的默认属性。

__getattr__():实现授权的关键点就是覆盖此方法,在代码中包含一个对getattr()内建函数的调用。
当引用一个属性时,Python解释器将试着在局部名称空间中查找这个名字,比如一个自定义的方法
或者局部实例属性。如果没有找到,则搜索类名称空间,以防一个类属性被访问。如果还是搜索不到,
则搜索对原对象开始授权请求,此时__getattr__()会被调用。

# 包装:所有属性都授权给原始对象
class WrapMe(object):
def __init__(self, obj):
self.__data = obj

# 为了得到原始对象,留一个后门
def get(self):
return self.__data

def __repr__(self):
return `self.__data`

def __str__(self):
return str(self.__data)

# 所有属性都授权给原来的对象
def __getattr__(self, attr):
return getattr(self.__data, attr)


# 包装一个文件对象,除了write(),其他所有属性都授权给文件对象
class CapOpen(object):
def __init__(self, fn, mode='r', buf=-1):
self.file = open(fn, mode, buf)

def __str__(self):
return str(self.file)

def __repr__(self):
return self.file

# 转成大写然后再写入
def write(self, line):
self.file.write(line.upper())

def __getattr__(self, attr):
return getattr(self.file, attr)




>新式类的高级特性-通用属性
old(not as good):
if type(obj) == type(0)
if type(obj) == types.IntType

better:
if type(obj) is type(0)

event better:
if isinstance(obj, int) # 可以是子类
if isinstance(obj, (int, long))
if type(obj) is int # 严格匹配

>新式类的高级特性- __slots__类属性
是一个类变量,由序列型对象组成,预定义了实例属性的集合。

>新式类的高级特性-特殊方法——__getattribute__()
任何时候访问实例的属性都会调用此方法。

>新式类的高级特性-描述符:
__get__(),__set__(), __delete__()特殊方法

示例:
# 创建一个描述符
class DevNull2(object):
def __get__(self, obj, typ=None):
print 'Accessing attribute.... ignoring'

def __set__(self, obj, val):
print 'Attempt to assign %r ... ignoring' % (val)


# 使用描述符
class C2(object):
foo = DevNull2()

>>> c2 = C2()
>>> c2.foo = 'bar'
Attempt to assign bar ... ignoring
>>> x = c2.foo
Accessing attribute.... ignoring


同时覆盖了__get__()及__set__()的类被称作数据描述符;
其他情况称作非数据描述符。

优先级别:
类属性
数据描述符
实例属性
非数据描述符
默认为__getattr__()


验证:
class DevNull1(object):
def __get__(self, obj, typ=None):
print 'Accessing attribute.... ignoring'


class DevNull2(object):
def __get__(self, obj, typ=None):
print 'Accessing attribute.... ignoring'

def __set__(self, obj, val):
print 'Attempt to assign %r ... ignoring' % (val)

class C(object):
attr1 = DevNull1()
attr2 = DevNull2()

c = C()
C.attr1 = 'aaa' # 类属性 
c.attr1 = 'attr1' # 实例属性
c.attr2 = 'attr2' # 数据描述符

print C.attr1
print c.attr1
print c.attr2

输出结果:
Attempt to assign 'attr2' ... ignoring
aaa
attr1
Accessing attribute .... ignoring
None

理解:
1.上面说的描述符就是一个类,用来代理在其他类中定义的类属性。
按照一定的优先级来判断:类属性,数据描述符,实例属性,非数据描述符。
即:
定义一个类属性:还是类属性。
定义一个实例属性:首先查看该属性是否已经在类定义中存在一个同名类属性描述符,
如果不存在,则为新定义的类属性;
如果存在,且为数据描述符,则数据描述符代理优先,
如果存在,且为非数据描述符,则实例属性优先。





>属性和property()内建函数
property(fget=None, fset=None, fdel=None, doc=None)


示例:
class HideX(object):
def __init__(self, x):
self.__x = x


def get_x(self):
return self.__x

def set_x(self, x):
assert isinstance(x, int), '"x" must be a integer!'
self.__x = x


x = property(get_x, set_x, doc = "Just hide x")

inst = HideX(10)
print inst.x #输出 10

HideX.x = 100
print HideX.x #输出100(类属性,最高优先级)

inst.x = 30
print inst.x #输出30

输出:


理解:
1.property()函数相当于帮我们定义了一个数据描述符代理类,简化了我们的代码。
只要把函数或者方法传递给property就可以了。
2.如果没有传递get方法,不能对实例属性取值;
如果没有传递set方法,不能对实例属性赋值;
如果没有传递del方法,不能删除实例属性。
3.属性的文档字符串只能通过类调用,例如:print HideX.x.__doc__。不能通过实例调用。


>元类 Metaclasses和__metaclass__
元类让你来定义某些类是如何创建的,从根本上说,赋予你如何创建类的控制权。
可以把元类想象成一个类中类,或是一个类,它的实例是其他的类。


在执行类定义时,解释器必须要知道这个类的正确的元类。
1.解释器首先会寻找类属性__metaclass__;
2.如果此属性存在,就将这个属性赋值给此类作为它的元类;
3.如果此属性没有定义,会继续向上查找父类中的__metaclass__;
4.如果父类中也没有发现__metaclass__属性,解释器会检查名为__metaclass__的全局变量;
5.如果存在此全局变量,就使用它作为元类;
6.如果不存在此全局变量,就说明是一个传统类,并用types.ClassType作为此类的元类。




在类定义时,元类通常传递三个参数到构造器:
类名;从基类继承数据的元祖;类的属性字典。


示例:
class MetaC(type):
# name: Foo
# bases:从基类type继承的数据元祖
# attrd:类Foo的属性字典
def __init__(cls, name, bases, attrd):
super(MetaC, cls).__init__(name, bases, attrd)
print "Create class %r at: %s" % (name, ctime())
print "base = ", bases
print "attrd = ", attrd


class Foo(object):
__metaclass__ = MetaC
version="1.0"

def __init__(self):
print "Initialized class %r at: %s" % (self.__class__.__name__, ctime())


===================== 执行环境 =======================
>可调用对象-函数
1.内建函数(BIFs)
c/c++写的,在_buildin_模块里,作为内建名称空间的一部分加载进系统(导入到解释器)。
BIF属性 描述
bif.__doc__ 文档字符串(或None)
bif.__name__ 字符串类型的文档名字
bif.__self__ 设置为None(保留给build-in方法)
bif.__module__ 存放bif定义的模块名字(或None)

2.用户定义的函数(UDF)
定义在模块的最高级别,作为全局名称空间的一部分装载到系统。
UDF属性 描述
udf.__doc__ 文档字符串
udf.__name__ 字符串类型的函数名字
udf.func_code 字节编译的代码对象
udf.func_defaults 默认的参数元祖
udf.func_globals 全局名字空间字典;和从函数内部调用globals(x)一样
udf.func_dict 函数属性的名称空间
udf.func_doc 文档字符串
udf.func_name 字符串类型的函数名字
udf.func_closure 包含了自由变量的引用的单元对象元祖




>可调用对象-方法
1.内建方法BIM
BIM属性 描述
bim.__doc__ 文档字符串
bim.__name__ 字符串类型的函数名字
bim.__self__ 绑定的对象

2.用户定义的方法(UDM)
UDM属性 描述
udm.__doc__ 文档字符串
udm.__name__ 字符串类型的方法名字
udm.__module__ 定义udm的模块的名字
udm.im_class 方法关联的类(对于绑定的方法;如果是非绑定,那么为要求udm的类)
udm.im_func 方法的函数对象
udm.im_self 如果绑定的话为相关联的实例;如果非绑定为None

>可调用对象-类
创建实例。


>可调用对象-类的实例
默认情况下,类的实例是不可调用的;
如果在类定义中实现了__call__()方法,那么类实例即可调用。
调用这样的实例对象等同于调用__call__()方法。


>代码对象
代码对象就是编译成字节码的代码块。
Python提供了大量的BIF来支持可调用/可执行对象。
内建函数和语句
callable(obj)
是否可调用。

compile(string, file ,type)
从type类型中创建代码对象;

string:要编译的代码。
file:代码存放的地方,通常设为""
type:表明代码对象的类型,有3个可能值:
"eval"---可求值的表达式。和eval()一起使用。
"single"-单一可执行语句。和exec 一起使用。
"exec"---可执行语句组。和exec一起使用。

eval(obj, globals=globals(), locals=locals()
对obj进行求值。
obj是已编译为代码对象的表达式,或者是一个字符串表达式。
可以给出全局或者/和局部名称空间。

exec obj
执行obj、单一的python语句或者语句的集合。
也就是说格式是代码对象或者字符串;
示例:
exec '''
for i in range(10):
print i,
'''

obj也可以是一个文件对象。
f = open("test.py"):
exec f

input(prompt='')
是eval和raw_input()的组合。
等同于eval(raw_input(prompt=''))。

>在运行时自动生成和执行Python代码
#!/usr/bin/env python


dashes = "\n" + "-" * 50


exec_dict = { \
"f":'''
for %s in %s: #一定要定格写,否则会报缩进错误
print %s
''',
"s":'''
%s = 0
%s = %s
while %s < len(%s):
print %s[%s]
%s = %s + 1
''',
"n":'''
%s = %d
while %s < %d:
print %s
%s = %s + %d
'''}

def main():
ltype = raw_input("loop type?(for/while)")
dtype = raw_input("Data type?(number/sequence)")

if dtype == "n":
start = input("starting value?")
stop = input("ending value?")
step = input("stepping value?")
seq = str(range(start, stop, step))
else:
seq = raw_input("Enter sequence: ")

var = raw_input("Iterative variable name?")

if ltype == "f":
exec_str = exec_dict['f'] % (var, seq, var)
elif ltype == "w":
if dtype == "s":
svar = raw_input("Enter sequence name?")
exec_str = exec_dict["s"] % \
(var, svar, seq, var, svar, svar, var, var, var)
elif dtype == "n":
exec_str = exec_dict["n"] % \
(var, start, var, stop, var, var, var, step)

print dashes
print "Your custom-generated code: " + dashes
print exec_str + dashes

print "Test execution of the code: " + dashes
exec exec_str
print dashes

if __name__ == "__main__":
main()




>执行其他Python程序-导入
当导入python模块后,会自动执行该模块的顶级代码。


>执行其他Python程序-execfile()
f = open(filename, 'r')
exec f
f.close()

或者

execfile(filename)

语法:
execfile(filename, globals = globals(), locals = locals())
globals, locals默认是当前的执行环境。



>执行其他Python程序-将模块作为脚本执行
在命令行直接执行一个python脚本,__name__ 的值为"__main__",会执行相关的if语句。
import导入一个模块会导致顶级代码执行,但是不会进入if __name__ == "__main__"的内部执行

因此,如果想执行一个python文件,必须以脚本方式来执行,这就需要输入文件全路径。
但是全路径不好找,是佛可以向import一样,由系统帮助查找呢?
对,这就需要一个参数
$ python -m python文件全路径




>执行其他非Python程序
二进制可执行文件,其他的shell脚本。

os.system(cmd)
执行程序cmd(字符串)
等待程序结束,返回退出代码.
cmd所有的输出都会传递到标准输出,因此system()通常和不会产生输出的命令一起使用。

os.popen(cmd, mode="r", buffering = -1)
执行字符串cmd,返回一个类文件对象作为运行程序通信句柄。
可以进行读取、写入。

示例:
import os
f = os.open('uname -a')
data = f.readline()
f.close()
print data

os.fork()
创建一个和父进程并行的子进程[通常和exec*()一起使用]
返回两次。。。一次给父进程,一次给子进程
子进程返回值永远为0;父进程返回值为子进程的PID。

os.execl(file, arg0, arg1,...)
用参数列表arg0, arg1执行文件file。
参数包括:用户的名字,搜索路径,shell,终端类型,本地化语言,机器类型,操作系统名字等。
os.execle(file, arg0, arg1,...env)
os.execlp(cmd, arg0, arg1,...)
在用户的搜索路径下搜索完全的路径文件名。
os.execlpe(cmd, arg0, arg1,...env)

os.execv(file, arglist)
os.execve(file, arglist, env)
os.execvp(cmd, arglist)
os.execvpe(cmd, arglist, env)

os.wait()
等待子进程完成。
通常和fork(),exec*()一起使用。
os.waitpid(pid, options)
等待指定的子进程完成。

os.spawn*(mode, file, args[, env])
与exec*()一样有多个版本。
此家族函数在一个新的进程中执行路径,args作为参数。

os.startfile(path)
用关联的应用程序执行路径。

subprocess模块
一个专门处理子进程的模块。

>受限执行
已经废弃。




>结束执行
sys.exit(status = 0) 
此函数会引发systemExit()异常,解释器会用给定的参数退出。

sys.exitfunc()
默认不可用,但是可以改写它以提供额外的功能。
当调用了sys.exit()并在解释器退出之前,就会调用这个函数。

示例:
import sys
prev_exit_func = getattr(sys, 'exitfunc', None)
def my_exit_func(old_exit = prev_exit_func):
if old_exit is not None and callable(old_exit):
old_exit()
# 改写
sys.exitfunc = my_exit_func

os._exit()
不执行任何清理工作立即退出python。
一般不应该在应用程序中使用。

os.kill()
模拟传统的unix函数来发送信号给进程。
参数:进程标示PID,和要发送的信号(SIGINT,SIGQUIT,SIGKILL)。

>各种操作系统接口
与进程相关的属性
os.uname()
获得系统信息(主机名,操作系统版本,补丁级别,系统架构)。

os.getuid()/setuid(uid)
获取/设置当前进程的用户UID。

os.getpid()/setpid(pid)
os.getgid()/setgid(gid)

os.getsid()/setsid(sid)
获取会话ID(SID)/创建返回新的SID。

os.umask(mask)
设置新的mask,同时返回之前的mask。

os.getenv(ev)/putenv(ev, value),environ
获取和设置环境变量ev的值。

os.geteuid()/seteuid()
获取/设置当前进程的有效uid.

os.getegid()/setegid()
获取/设置当前进程的有效组ID。


os.getlogin()
返回运行当前进程的用户登录。

os.times()
返回各种进程时期的元组。


os.strerror(code)
返回和错误代码对应的错误信息。




移动客户端 iOS版
程序版本: 1.0.4
支持手机: 需要 iOS 5.0 或更高版本, 建议使用6.1以后版本以获取更稳定的性能, 支持设备包括iPhone4S, iPhone5/5s/5c, iPod Touch 5, new iPad, iPad 4, iPad Mini.
 
移动客户端 Android版 (Google Play | 本地下载)
设备要求: 支持BLE, 安卓系统4.3, 试用版本下载已经发布到了Google Play, 欢迎体验并提出意见以协助我们改进.
使用手册
pdf版本用户使用手册文件
技术规格文档
pdf版本技术规格文件.


移动客户端 iOS版
程序版本: 2.0.4
支持手机: 需要 iOS 5.0 或更高版本, 此App已针对iPhone 5进行优化.
 
移动客户端 Android版
程序版本: 1.0.5
Android系统版本: 要求2.3.3以上, 推荐2.3.6以上
 
os.getloadavg()
返回代表在过去1,5,15分钟内的系统平均负载值的元组。






============================== 正则表达式 =========================
>特殊符号与字符
记号 说明
literal 匹配字符串的值
re1|re2 匹配正则表达式re1 或 re2
. 匹配任何字符(换行符除外)
^ 匹配字符串的开始,也可以使用\A
$ 匹配字符串的结尾,也可以使用\Z
* 匹配前面出现的正则表达式零次 或 多次
+ 匹配前面出现的正则表达式一次 或 多次
? 匹配前面出现的正则表达式零次 或 一次
{N} 匹配前面出现的正则表达式 N 次
{M,N} 匹配重复出现 M 次 到 N 次的正则表达式
[...] 匹配字符组里出现的任意字符
[..x-y..] 匹配从字符 x 到 y 中的任意一个字符
[^...] 不匹配此字符集中出现的任何一个字符,包括某一范围内的字符。
(*|+|?|{})? 用于上面出现的任何“非贪婪”版本。重复匹配次数符号(*,+,?,{})
(...) 匹配封闭括号中正则表达式,并保存为子组。
一对圆括号和正则表达式一起使用,可以实现这2个功能:
对正则表达式进行分组
匹配子组
\d 匹配任何数字,和[0-9]一样。
\D \d的反义:匹配任何非数字
\w 匹配任何数字字母字符,和[A-Za-z0-9]相同。
\W \w的反义
\s 匹配任何空白字符,和[\n\t\r\v\f]一样。
\S \s的反义
\b 匹配单词边界
\B \b反义
\nn 匹配已保存的子组。
\c 逐一匹配特殊字符c(即:取消它的特殊含义,按字面匹配)。
\A 匹配字符串的起始
\Z 匹配字符串的结束


>re模块:核心函数和方法
re模块的函数
compile(pattern, flags=0)
对正则表达式模式pattern进行编译
返回一个正则表达式(regex)对象。

match(pattern, string, flags=0)
尝试用正则表达式模式pattern匹配字符串string
从字符串的开头进行匹配
如果匹配成功,返回一个匹配对象;否则返回None

search(pattern, string, flags=0)
在字符串string中查找正则表达式模式pattern的第一次出现
查找字符串中模式首次出现的位置
如果匹配成功,返回一个匹配对象;否则返回None

findall(pattern, string[, flags])
在字符串string中查找正则表达式模式pattern的所有非重复出现
返回一个匹配对象的列表

finditer(pattern, string[, flags])
和findall相同,但返回的不是列表,而是迭代器。
对于每个匹配,该迭代器返回一个匹配对象。

split(pattern, string, max=0)
根据正则表达式pattern,把字符串string分割成一个列表
返回成功分割的列表

sub(pattern, repl, string, max=0)
把字符串string中所有匹配正则表达式pattern的地方都换成字符串repl,
如果max没有给出,则对所有的地方进行替换。


group(num=0)
返回全部匹配对象(或指定编号是num的子组)

groups()
返回一个包含全部匹配的子组的元祖(没有匹配成功时返回一个空元祖)。




>re模块函数
如果使用re模块中的函数,需要传入模式字符串(正则表达式)。

>regx对象
如果先使用re.compile()编译正则表达式模式字符串之后,得到regx对象,然后就可以使用该对象的各种方法。


>匹配对象
匹配对象是在match()或者search()被成功调用之后所返回的结果。
有这个方法:group(), groups()




>原始字符串
有一些字符在ASCII码里表示特殊字符,例如:\b表示退格。 
在正则表达式中,\b表示匹配单词边界。


如果在正则表达式中直接写'\b'会被认为的ASCII码中的退格符。
因此需要使用反斜线对\b进行转义(跳脱):\\b。但是这样以来就比较晦涩,不好理解。
因此可以使用原始字符串r'\b',这样就不会被认为是ASCII码的退格符了。




=============================== 网络编程 =======================================
>套接字
套接字类型(地址簇):
1.基于文件型的:AF_UNIX
两个进程都运行在cket_family, socket_type, protocol=0)
同一台机器上,底层结构是由文件系统来支持的。
2.基于网络型的:AF_INET
3.一些其他的套接字类型,python不支持。
4.AF_NETLINK:Python2.5中加入:让用户代码与内核代码之间的IPC可以使用标准BSD套接字接口。



>面向连接的套接字(流套接字)
TCP套结字:SOCK_STREAM


>无连接的套接字
UDP套接字:SOCK_DGRAM

>Python套接字
socket.socket(so
服务端套接字函数 描述
s.bind() 绑定地址(主机,端口号)到套接字
s.listen() 开始TCP监听
s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来


客户端套接字函数
s.connect() 主动初始化TCP服务器连接
s.connect_ex() connect()的扩展版本,出错时返回错误码,而不是抛异常


公共用户的套接字函数
s.recv() 接收TCP数据
s.send() 发送TCP数据
s.sendall() 完整发送TCP数据


s.recvfrom() 接收UDP数据
s.sendto() 发送UDP数据


s.getpeername() 连接到当前套接字的远端的地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字


阻塞套接字函数
s.setblocking() 设置套接字的阻塞与非阻塞模式
s.settimeout() 设置阻塞套接字操作的超时时间
s.gettimeout() 获取阻塞套接字操作的超时时间

面向文件的套接字函数
s.fileno() 套接字的文件描述符
s.makefile() 创建一个与该套接字关联的文件


>套接字模块属性
数据属性 描述
AF_UNIX, Python支持的套接字家族
AF_INET,
AF_INET6

SO_STREAM, 套接字类型
SO_DGRAM


has_ipv6 标示是否支持IPv6的标志量

异常
error 套接字相关错误
herror 主机和地址相关的错误
gaierror 地址相关的错误
timeout 超时

函数
socket() 创建一个套接字对象
socketpair() 创建一对套接字对象
fromfd() 用一个已经打开的文件描述符创建一个套接字对象

数据属性
ssl() 在套接字初始化一个安全套接字层(SSL),不做证书验证。
getaddrinfo() 得到地址信息
getfqdn() 返回完整的域的名字
gethostname() 得到当前主机名
gethostbyname() 由主机名得到对应的IP地址
gethostbyname_ex() 扩展版本,返回主机名,主机所有的别名和IP地址列表。
gethostbyaddr() 由IP地址得到DNS信息。

getprotobyname()由协议名得到对应的号码
getservbyname() 由服务名得到相应的端口号
getservbyport() 由端口号得到相应的服务名

ntol()/ntohs() 把一个整数由网络字节序转成主机字节序。
htonl()/htons() 把一个整数由主机字节序转成网络字节序。

inet_aton() 把IP地址转成32位整数
inet_ntoa() 与上面相反

inet_pton() 把IP地址转成二进制格式
inet_ntop() 相反


===================== 网络客户端编程 ===================
>FTP
使用TCP。
客户端与服务端都有2个套接字:
一个是控制和命令端口21,另一个是数据端口(有时是20)。


从服务器端看,有主动和被动两种模式。
主动模式:服务器主动使用20端口连接客户端的数据端口。
被动模式:服务器告诉客户端自己的一个随机数据端口,客户端必须主动建立数据连接。


浏览器也可以说是一个FTP客户端:
ftp://user:password@host/path?attr1=val2&attr2=val2...


>Usenet与新闻组
NNTP:网络新闻传输协议。 port:119
伪码:
from nntplib import NNTP
n = NNTP('your.nntp.server')
rst,ct,fst,lst,group = n.group('group_name')
...
n.quit()


>电子邮件
MTA:消息传输代理
MX:邮件交换 Mail eXchange
MTS:消息传输系统(MTA之间通讯使用的协议),例如:
SMTP:简单邮件传输协议,port:25,用于发送/传输邮件。


伪码:
from smtplib import SMTP
n = SMTP('smtp.yourdomain.com')
...
n.quit()




MUA:邮件用户代理,即:在个人电脑中运行的邮件客户端。
主要目的是下载邮件,但一般也实现SMTP去发送邮件。
下载邮件的2个协议:
POP:邮局协议,用于下载邮件的第一个协议。最新版本POP3
IMAP:交互式文件访问协议。

伪码:
from poplib import POP3
p = POP3('pop.python.is.cool')
p.user(...)
p.pass_(...)
...
p.quit()




================= 多线程编程 ==================
>GIL:全局解释器锁
保证同一时刻只能有一个线程在Python虚拟机里执行。




>thread模块:尽量不使用
模块函数:
start_new_thread(function, args, kwargs=None)
产生一个新的线程,在新线程中使用指定的参数(元组)和可选的kwargs来调用这个函数。


allocale_lock()
分配一个LockType类型的锁对象


exit()
退出线程



LockType类型锁对象的方法
acquire(wait=None)
尝试获取锁对象


locked()
如果获取了锁对象返回True,否则返回False


release()
释放锁




>threading模块
模块对象 描述
Thread 表示一个线程的执行的对象
Lock 锁原语对象
RLock 可重入锁对象
Condition 条件变量对象,能让一个线程停下来,等待其它线程满足了某个“条件”
Event 通用的条件变量。多个线程可以等待某个事件的发生,在事件发生后,所有线程都会被激活。
Semaphore 为等待锁的线程提供一个类似“等候室” 的结构
BoundedSemaphore 与Semaphore类似,但不允许超过初始值。
Timer 与Thread相似,只是,它要等待一段事件后才开始运行。






>守护线程
即表示这个线程不重要。在进程退出时,不用等待这个线程退出。thread.setDeamon(True).


>Thread类
3种创建线程的方法:
1.创建一个Thread的实例,传给它一个函数
例如:
def func(num, sec);
pass
thread = threading.Thread(target=fun, args=(1,10))
thread.start()

2.创建一个Thread的实例,传给它一个可调用的类对象
例如:
class ThreadFun(object):
def __init__(self, func, args, name=''):
self.name = name
self.func = func
self.args = args
def __call__():
apply(self.func, self.args)

def func(num, sec);
pass
thread = threading.Thread(target=ThreadFunc(func, (1, 10), func.__name__))
thread.start()


3.从Thread派生出一个子类,创建一个这个子类的实例
例如:
class MyThread(threading.Thread):
       def __init__(self, func, args, name=''):
               threading.Thread.__init__(self)
               self.name = name
               self.func = func
               self.args = args

       def run(self):
               apply(self.func, self.args)


def loop(n, sec):
       sleep(sec)


t = MyThread(loop, (i, loops[i]), loop.__name__)
t.start()




对象函数
start()
run()
join(timeout=None)
getName()
setName(name)
isAlive()
isDaemon()
setDaemon(daemonic) 在start()之前设置


activeCount() 当前活动的线程对象的数量
currentThread() 返回当前线程对象
enumerate() 返回当前活动线程的列表
settrace(func) 为所有线程设置一个跟踪函数
setprofile(func) 为所有线程设置一个profile函数






>Queue模块
可以用来进行线程之间的通讯,共享数据。








============================= 图形用户界面编程 ============================
>Tkinter
Python的默认GUI库,它基于Tk工具集。


Tk最初是为工具命令语音(Tcl)设计的,后来Tk流行后被移植到许多其它脚本语言中。

Tk有两个坐标管理器用来协助把组件放在正确的位置上:packer, Grid。



>Tk组件:15种
Button
Canvas
Checkbutton
Entry
Frame
Label
Listbox
Menu
Menubutton
Message
Radiobutton
Scale
Scrollbar
Text
Toplevel




>GUI中使用偏函数
from functools import partial
import Tkinter

root = Tkinter.Tk()
MyButton = partial(Tkinter.Button, root, fg="white", bg="blue")
b1 = MyButton(text="Button 1")




==================== Web 编程 ==========================
>C/S架构
客户端:用户使用的浏览器是其中之一。
通讯协议:HTTP


>URL
prot_sch://net_loc/path;params?query#frag

prot_sch 网络协议或下载规划
net_loc 服务器位置,例如:user:passwd@host:port
FTP才可能需要user:passwd
port不写的话默认80
path 限定文件或CGI应用程序的路径
parmas 可选参数
query &连接键值对
frag 拆分文档中的特殊锚




>urlparse模块




>urllib模块
f= urllib.urlopen(urlstr, postQueryData=None)
打开给定URL字符串与web连接,返回文件类对象。
如果没有给定协议或下载规划,或者文件规划早已传入,会打开一个本地文件。
f.read([bytes])
f.readline()
f.readlines()
f.close()
f.fileno()
f.info()
f.geturl()

urllib.urlretrieve(usrstr, localfile=None, downloadStatusHook=None)
把整个HTML文件下载到本地硬盘上。

urllib.quote(urldata, safe='/')
对字符串进行编码,使之符合URL字符串标准。
一些不能被打印或不被web服务器视作有效URL接收的特殊字符串必须被转换。
不需要转换的有:字母,数字,逗号,下划线,句号,斜线。

urllib.quote_plus()
将空格编码成+

urllib.unquote()
urllib.unquote_plus()
相反,把所有编码为“%xx”式的字符都转换成他们的ASCII码值。

urllib.urlencode(dict)
把dict字典编码成urlopen需要的键值对形式的字符串。




>CGI:帮助Web服务器处理客户端数据
客户端<--->Web服务器<--->CGI程序
CGI:编程语言通常有Perl, PHP, C/C++, python


web测试服务器:python -m CGIHTTPServer










=============================== 数据库编程 =====================================
>数据库
关系型数据库管理系统通常支持多个数据库,例如:销售库,市场库,客户支持库等等。
如果使用的关系数据库管理系统是基于服务器胡,这些数据库就都在同一台服务器上。
一些简单的关系型数据库没有服务器,例如:sqlite和Gadfly是基于文件胡关系型数据库。



>SQL
创建数据库
CREATE DATAASE test;
GRANT ALL ON test.* to user(s);

选择要使用的数据库
USE test;

删除数据库
DROP DATABASE test;

创建表
CREATE TABLE users (login VARCHAR(8), uid INT, prid INT);


删除表
DROP TABLE users;

插入行
INSERT INTO user VALUES('name', 311, 1);

更新行
UPDATE users SET prid=4 WHERE prid=2;
UPDATE users SET prid=1 WHERE uid=311;

删除行
DELETE FROM users WHERE prid=%d;
DELETE FROM users;


>DB-API
是一个规范。定义了一系列必须的对象和数据库存取方式,以便为各种各样的底层数据库
系统和多种多样的数据库接口程序提供一直的访问接口。

也就是:一个数据库模块中,必须提供DB-API规范中定义的属性。
属性名 描述
apilevel DB-API模块兼容的版本号,默认"1.0"
threadsafety 线程安全级别
0:多个线程不能共享此模块
1:线程可以共享模块,但不能共享连接。
2:线程可以共享模块和连接,但不能共享游标。
3:线程可以共享模块,连接和游标。
paramstyle 该模块支持的SQL语句参数风格
connect() 连接函数


>连接对象
要与数据库进行通信,必须先和数据库建立连接。
连接对象方法:
close()
commit()
rollback()
cursor()
errorhandler(cxn, cur, errcls, errval)


>游标对象
一个游标允许用户执行数据库命令和得到查询结果。
对象属性或方法
arraysize
connection
description
lastrowid
rowcount
callproc(func[, args])
close()
execute(op[, args])
executemany(op, args)
fetchone()
fetmany([size=cursor.arraysize])
fetchall()
__iter__()
messages
next()
nextset()
rownumber
setinput- sizes(sizes)
setoutput- seize(size[, col])


>类型对象和构造器
在Python对象和数据库对象之间需要数据格式的转换。


>Python 支持的数据库
商业关系型数据库管理系统:
Informix
Sybase
Oracle
MS SLQ Server
DB/2
SAP
Interbase
Ingres

开源关系型数据库管理系统:
MySQL(1个接口API:MySQLdb, 又名:MySQL-python)
PostgreSQL(3个接口API:psycopg, PyPgSQL, PyGreSQL)
SQLite(1个接口API:sqlite3)
Gadfly

数据库APIs:
JDBC
ODBC

>对象-关系管理器(ORMs)
将绝大多数纯 SQL 层功能抽象为 Python 对象,这样就不需要编写 SQL 语句也能操作数据库。

知名的Pyhton ORM模块是:SQLAlchemy 和 SQLObject。




=================== 扩展 Python ===================
>创建Python 扩展步骤:
1.创建应用程序代码
例如:Extend1.c  
2.利用样版来包装代码
1)包含Python的头文件
2)为每个模块的每一个函数增加一个型如PyObject *Module_func()的包装函数
3)为每个模块增加一个型如PyMethodDef ModuleMethods[]的数组
4)增加模块初始化函数void initModule()


Python对象与C语言变量之间的转换:
PyArg_ParseTuple()
把Python传过来的参数转为C。
PyArg_ParseTupleAndKeywords()
同上。同时解析关键字参数。
PyObject *Py_BuildValue()
把C的数据转为Python的一个对象或者一组对象,然后返回。


转换格式:Python 与 C/C++
Format Code Python Type C/C++ Type
s str char*
z str/None char*/NULL
i int int
l long long
c str char
d float double
D complex Py_Complex*
O (any) PyObject*
S str PyStringObject
3.编译与测试
使用 distutils 包来编译、安装和分发
1)创建setup.py
2)运行setup.py来编译、连接代码
3)在Python中导入C代码模块,调用。


>引用计数
用于 Python 对象引用计数的宏
Py_INCREF(obj)
Py_DECREF(obj)


================= 其它话题 =================









































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IOT物联网小镇

赏点银子去植发

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值