1.1. 概述
Python是一个脚本解释器, 可以从命令行运行脚本, 也可以在脚本上双击, 象运行其他应用程序一样。它还是一个交互 shell, 可以执行任意的语句和表达式。
Python 的交互 shell 可以计算任意的 Python 表达式, 包括任何基本的数学表达式。交互 shell 可以执行任意的 Python 语句, 包括 print 语句。也可以给变量赋值, 并且变量值在 shell 打开时一直有效(一旦关毕交互 Sheel , 变量值将丢失)。
表格 1 编程语言数据类型的比较
静态类型定义语言 | 一种在编译期间数据类型固定的语言。大多数静态类型定义语言是通过要求在使用所有变量之前声明它们的数据类型来保证这一点的。 Java 和 C 是静态类型定义语言。 |
动态类型定义语言 | 一种在运行期间才去确定数据类型的语言, 与静态类型定义相反。 VBScript 和 Python 是动态类型定义的, 因为它们确定一个变量的类型是在您第一次给它赋值的时候。 |
强类型定义语言 | 一种总是强制类型定义的语言。 Java 和 Python 是强制类型定义的。您有一个整数, 如果不明确地进行转换 , 不能将把它当成一个字符串。 |
弱类型定义语言 | 一种类型可以被忽略的语言, 与强类型定义相反。 VBScript 是弱类型定义的。在 VBScript 中, 您可以将字符串 ’12′ 和整数 3 进行连接得到字符串’123′, 然后可以把它看成整数 123 , 所有这些都不需要任何的显示转换。 |
1.2. 函数声明
def function_name([arguments]):
‘optional documentation string’
function_suite
a. arguments参数之间用逗号隔开。Python函数定义中不需要提定返回值的数据类型,也不需要指定是否有返回值。每个 Python 函数都返回一个值;如果函数执行过 return 语句, 它将返回指定的值, 否则将返回 None ( Python 的空值) 。Python 中没有子程序,只有函数, 所有的函数都有返回值,并且所有的函数都以 def 开始。
b. 文档化函数:函数声明后第一个没有赋值的字符串,也可使用三引号括起。使用函数的属性__doc__来调用这个字符串。
def buildConnectionString(params):
“””Build a connection string from a dictionary of parameters.
Returns string.“””
c. print语句实用规则是print(value, …, sep=’ ‘, end=’\n’, file=sys.stdout),Python的print语句调用str()函数显示对象,交互式解释器则调用repr()函数来显示对象。
表格 2 对新Python程序员有用的内建函数
函数 | 描述 |
dir([obj]) | 显示对象的属性,如果没有提供参数,这显示全局变量 |
help([obj]) | 以一种整齐美观的形式,显示对象的文档字符串,如果没有提供任何参数,则会进入交互式帮助 |
int(obj) | 将一个对象转换为整型 |
len(obj) | 返回对象的长度 |
open(fn,mode) | 以mode方式打开一个文件名为fn的文件 |
range([[start,]stop[,step]]) | 返回一个整型列表。起始值为start,结束值为stop-1,start默认值为0,step默认值为1 |
raw_input(str) | 等待用户输入一个字符串,可以提供一个可选的参数str用作提示信息。 |
str(obj) | 将一个对象转换为字符串 |
type(obj) | 返回对象的类型(返回值本身是一个type对象) |
1.3. Python常用习惯
a. 反斜杠(\)继续上一行,Python文件以模块形式组织。下划线(_)返回最后一个表达式的值。
b. 命令行选项:
-d 提供调试输出
-o生成优化字节码(pyo文件)
-s 不导入site模块以启动时查找Python路径
-v 冗余输出(导入语句详细追踪)
-m mod 将一个模块以脚本形式输出
-Q opt 除法选项
-c cmd 运行时以命令行字符串形式提交的Python脚本
file 从给定的文件运行Python脚本
c. raw_input()内建函数:读取标准输入,并将读取到的数据赋值给指定的对象,键入EOF字符则引发EOFError。可以加在脚本最后一行,用来使程序执行时保持窗口开着。Python中函数input和raw_input可以看做是def input(prompt):return eval(raw_input(prompt)) 即调用eval函数来看输入是什么,实际上你甚至可以输入表达式,Python会计算表达式的值来返回。
d. Python 函数没有明显的 begin 和 end, 没有花括号, 用于标函数的开始和结束。 唯一的分隔符是一个冒号 (:), 接着代码本身是缩进的。Python 使用硬回车来分割语句, 冒号和缩进来分割代码块。C++ 和 Java 使用分号来分割语句, 花括号来分割代码块。
e. 可使用help(函数名)来查询相应函数帮主信息。
1.4. 标识符
a. 任何时刻只有一个名字绑定,不支持重载标识符。内建(built-in)是__builtins__模块的成员,由解释器自动导入,可看作是任何一级的Pythong代码的全局变量。
b. 专用下划线标识符:_xxx不用‘form modules import *’导入,_xxx_系统定义的名字,_类中私有变量名。
c. 系统变量__name__决定运行是的模块是被导入还是直接执行:为模块名则导入,为‘__main__’则直接运行。
d. “Pythonic”:以Python的方式去编写代码、组织、逻辑和对象行为。
表格 3 Python关键字
and | as | assert | break |
class | continue | def | del |
elif | else | except | exec |
finally | for | from | global |
if | import | in | is |
lambda | not | or | pass |
raise | return | try | |
while | with | yield | None |
1.5. 变量声明
myParams = <表达式>
a. 命名规则:以字母或下划线开头,其他字符可以是数字、字母或下划线。大小写敏感。Python是动态类型语言,不需要预先声明变量类型,变量值和类型在赋值时被初始化。
b. Python赋值语句不返回值,不支持类似x++或—x这样的单目双重运算符,允许符合赋值(*=)、多重赋值和“多元”赋值
c. 变量的赋值可以是一条被分成了多行的命令, 用反斜线 (“\”) 作为续行符,当一条命令用续行符 (“\”) 分割成多行时, 后续的行可以以任何方式缩近, 此时 Python 通常的严格的缩近规则无需遵守。
d. Python 有局部变量和全局变量之分, 但没有明显的变量声明。变量通过首次赋值产生, 当超出作用范围时自动消亡。Python 不允许引用一个未被赋值的变量, 试图这样做会引发一个异常。
e. Python的一种编程简写是一次使用序列来给多个变量赋值。Python 中,可以使用内置的 range 函数和多变量赋值的方法来快速进行赋值,与C++中的枚举相似。如:
(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)
1.6. 注释
a. 使用#符号标示注释;
b. 在模块、类或者函数起始添加一个字符串起文档作用;
c. 使用三引号标示注释。
二、数据类型
2.1. 基本数据类型
有符号整型、长整型(仅受限于用户计算机的虚拟内存总数,可由整型自动转换)、布尔值、浮点值、复数(a+bj或a+bJ)
△ 引入decimal模块使用decimal类型(十进制浮点型)
?二进制表示中有一个无限循环:1.1 → 1.10000……1
a. 复数拥有real、imag、conjugete()属性,coerce()内建函数实现强制类型转换。
b. 除法引入指令from __future__ import division使整型除法保留小数部分,//操作符执行“地板除”。浮点数取余表达式:x-(math.floor(x/y)*y);复数取余表达式:x-(math.floor((x/y).real)*y)
c. 冥运算比其左侧操作数的一元操作符优先级高,比其右侧操作数的一元操作符的优先级低。?4xx-1报错
d. Python支持标准位运算(仅适用于整型):取反(~),按位与(&),或(|)和异或(^)、左移(<<)、右移(>>)
△ 复数当成正数的2进制补码处理;
△ 左移好右移N位等同于无溢出检查2的N次幂运算:2**N;
△ 对长整形,位操作符使用一种未修改的2进制补码形式,使得符号位无限向左扩展。
数字类型相关模块:decimal(十进制浮点运算类Decimal)、array(高级数字数组)、math/cmath(标准C库数学运算函数,复数在cmath中)、operator(数字操作符的函数实现)、random(各种伪随机数生成器)
表格 4 数值工厂函数
类(工厂函数) | 操作 |
boll(obj) | 返回obj对象的布尔值,即obj.__nonzero__方法的返回值 |
int(obj,base=10) | 返回一个字符串或数值对象的整型表示,类似string.atoi() |
long(obj,base=10) | 返回一个字符或数据对象的长整型表示,类似string.atol() |
float(obj) | 返回一个字符串或数据对象的浮点型表示,类似string.atof() |
complex(str) or
complex(real,inag=0.0) | 返回一个字符串的复数标识,或者根据给定的实数(及一个可选的虚数部分)生成一个复数对象 |
表格 5 数值运算内建函数
函数 | 功能 |
abs(num) | 返回num的绝对值 |
coerce(num1,num2) | 将num1和num2转换为同一类型,然后以一个元组的形式返回 |
divmod(num1,num2) | 除法-取余运算的结合。返回一个元组(num1/num2,num1%num2),对浮点数和复数的商进行下舍入 |
pow(num1,num2, mod=1) | 取num1的num2次方,如果提供mod参数,则计算结果再对mod进行取余运算 |
round(flt,ndig=1) | 接受一个浮点型flt并对其四舍五入,保存ndig位小数,不提供ndig则默认为0位 |
表格 6 仅适用于整型的内建函数
函数 | 操作 |
hex(num) | 将数字转换成十六进制数并以字符串形式返回 |
oct(num) | 将数字转换成八进制数并以字符串形式返回 |
chr(num) | 将ASCII值的数字转换成ASCII字符,范围只能是0<=nuum<=255 |
ord(chr) | 接受一个ASCII或Unicode字符,返回相应的ASCII值或Unicode值 |
unichr(num) | 接受Unicode码值,返回其对应的Unicode字符,接受码值返回由Python构建于UCS-2还是UCS-4决定 |
2.2. 映射和集合类型
字典(Dictionary):Python中唯一映射类型,作为可变的哈希表实现。
dictionaryName = {“key1“:”value1“, “key2“:”value2“……}
- Dictionary定义了键和值之间一对一的关系,变量可以任意取名,Python在内部会记录下其数据类型。value可以为任意的数据类型,key的要求较为苛刻一些。
- 重复赋值, 将简单覆盖原有的值。Dictionary 的 key 是大小写敏感的。可以通过key来引用value,不能通过value引用key。
- 字典相关函数:type()、str()、cmp();映射类型相关函数:dict()、len()、hash()。del dictionaryName["key"]删除dictionary中独立元素;dictionaryName.clear() 删除dictionary中所有元素。例7.1、7.2
表格 7 映射类型内建方法
方法名字 | 操作 |
dict.clear() | 删除字典中所有元素 |
dict clear() | 返回字典(浅复制)的一个副本 |
dict.fromkeys(seq,val=None) | 创建并返回一个新字典,以seq中的元素做该字典的键,val做该字典中所有键对应的初始值 |
dict.get(key,default=None) | 对字典dict中的键key,返回它对应的值value,如果字典中不存在此键,则返回default值 |
dict.has_key(key) | 如果键在字典中存在,返回True,否则返回False,由in和not in代替 |
dict.items() | 返回一个包含字典中键、值对元组的列表 |
dict.keys() | 返回一个包含字典中键的列表 |
dict.iter() | 方法iteritems()、iterkeys()、itervaluse()与它们对应的非迭代方法一样,不同的是它们返回一个迭代子,而不是一个列表 |
dict.pop(key[,default]) | 和方法get()相似,如果字典中key键存在,删除并返回dict[key];如果key键不存在,且没有给出default值,则引发KeyError异常 |
dict.setdefault(key,default = None) | 和方法set()相似,如果字典中不存在key键,由dict[key]=default为它赋值 |
dict.update(dict2) | 将字典dict2的键-值对添加到字典dict |
dict.values() | 返回一个包含字典中所有值的列表 |
- d. 集合对象(Set)是一组无序排列的可哈希的值。集合类型操作符:in,not in,布尔操作符,联合(|)、交集(&)、差补()、相对补集(-)、对称差分(^)(=、&=、-=、^=)
表格 8 集合类型的操作符、函数和方法
函数/方法名 | 等价操作符 | 说明 |
所有集合类型 | ||
len(s) | 集合基数:集合s中元素个数 | |
set([obj]) | 可变集合工厂函数:ojb必须是支持迭代的,由obj中的元素创建集合,否则创建一个空集合 | |
frozenset([obj]) | 不可变集合工厂函数:执行方式好set()方法相同,但它返回的是不可变集合 | |
obj in s | 成员测试 | |
obj not in s | 非成员测试 | |
s == t | 等价测试 | |
s != t | 不等价测试 | |
s < t | (严格意义上)子集测试 | |
s.issubset(t) | s <= t | 子集测试 |
s > t | (严格意义上)超集测试 | |
s.issuperset(t) | s >= t | 超集测试 |
s.union(t) | s | t | 合并操作 |
s.intersec-tion(t) | s & t | 交集操作 |
s.difference(t) | s – t | 差分操作 |
s.symmetric_fifference(t) | s ^ t | 对称差分操作 |
s.copy() | 赋值操作:返回s的(浅复制)副本 | |
仅适用于可变集合 | ||
s.update(t) | s |= t | (Union)修改操作:将t中的成员添加s |
s.intersection_update(t) | s &= t | 交集修改操作:s中仅包括s和t中共有的成员 |
s.difference_update(t) | s -= t | 差修改操作:s中仅包括属于s但不属于t的成员 |
s.symmetric_difference_ update(t) | s ^= t | 对称差分修改操作:s中包括仅属于s或仅属于t的成员 |
s.add(obj) | 加操作:将obj添加到s | |
s.remove(obj) | 删除操作 | |
s.discard(obj) | 丢弃操作:remove()的友好版本,如果s中存在ojb,从s中删除它 | |
s.pop() | Pop操作:移除并返回s中的任意一个值 | |
s.clear() | 清除操作:移除s中的所有元素 |
2.3. 序列
序列类型操作符:成员关系操作符(in、not in)、连接操作符(+)、重复操作符(*)、切片操作符([],[:],[::])、切片索引的更多内容
序列类型函数(有返回值):cmp(), len(), max(), min(), sorted(), reversed(), enumerate(), zip(), reduce(), sum(), list()和tuple()
表格 9 序列类型转换工厂函数
函数 | 含义 |
list(iter) | 把迭代对象转换为列表 |
str(obj) | 把obj对象转换成字符串(对象的字符串表示法) |
unicode(obj) | 把对象转换成Unicode字符串(使用默认编码) |
basestring() | 抽象工厂函数,其作用仅仅是为str和unicode函数提供父类,所以不能被实例化,也不能被调用 |
tuple(iter) | 把一个迭代对象转换为一个元组对象 |
表格 10 序列类型可用的内建函数
函数名 | 功能 |
enumerate(iter) | 接受一个可迭代对象作为参数,返回一个enumerate对象(同时也是一个迭代器),该对象生成由iter每个元素的index值和item值组成的元组 |
len(seq) | 返回seq的长度 |
max(iter,key=None)or max(arg0,arg1…,key=None) | 返回iter或(arg0,arg1,…)中的最大值,如果指定了key,这个key必须是一个可以传给sort()方法的,用于比较的回调函数 |
min(iter,key=None)or min(arg0,arg1…,key=None) | 返回iter或(arg0,arg1,…)里面的最小值,如果指定了key,这个key必须是一个可以传给sort()方法的,用于比较的回调函数 |
reversed(seq) | 接受一个序列作为参数,返回一个可逆序访问的迭代器 |
sorted(iter,func=None, key=None,reverse=False) | 接受一个可迭代对象作为参数,返回一个有序的列表;可选参数func、key和reverse的含义跟list.sort()内建函数的参数定义一样 |
sum(seq,init=0) | 返回seq和可选参数init的总和,其效果等同于reduce(
operator.add,seq,init) |
zip([it0,it1,…itN]) | 返回一个列表,其第一个元素是it0、it1…这些元素的第一个元素组成一个元组,第二个…依此类推 |
2.3.1. 字符串(不可改变,比较操作中按照ASCII值的大小来比较)
a. 把重复操作z作为参数放在循环中进行是非常低效的;
b. Python语法允许在源码中把几个字符串连在一起写,来构建新字符串,使用分号隔开,可加入注释;
c. 如果把一个普通字符串和一个Unicode字符串作连接处理,Python会在连接操作前先将普通字符串转换为Unicode字符串。
d. 字符串模板:原始字符串操作符(r/R)(原始字符串对每个字符都使用原意);Unicode字符串操作符(u/U)。
e. 字符串类型函数(有返回值):raw_input(), str(), unicode(), chr(), unichr(), ord()
f. Python中允许使用三引号使一个字符串跨多行,并且可以包含换行符、制表符和其他特殊符号。
Unicode:P127
字符串内建函数:…………
表格 11 反斜杠开头的转义字符
八进制 | 十进制 | 十六进制 | 字符 | 说明 | |
\0 | 000 | 0 | 0×00 | NUL | 空字符NUL |
\a | 007 | 7 | 0×07 | BEL | 响铃字符 |
\b | 010 | 8 | 0×08 | BS | 退格 |
\t | 011 | 9 | 0×09 | 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 | 0×22 | “ | 双引号 |
\’ | 047 | 39 | 0×27 | ‘ | 单引号 |
\\ | 134 | 92 | 0x5C | \ | 反斜杠 |
表格 12 与字符串类型有关的模块
模块 | 描述 | 模块 | 描述 |
string | 字符串操作相关函数和工具 | re | 正则表达式 |
struct | 字符串和二进制之间的转换 | c/StringIO | 字符串缓冲对象类似file |
base64 | Base16、32和64数据编解码 | codecs | 解码器注册和基类 |
crypt | 进行单方面加密 | difflib | 找出序列间的不同 |
hashlib | 多种不同安全哈希算法和信息摘要算法是API | hma | HMAC信息鉴权算法的Python实现 |
md5 | RSA的MD5信息摘要鉴权 | rotor | 提供多平台的加解密服务 |
sha | NIAT的安全哈希算法SHA | stringprep | 提供用于IP协议的Unicode字符 |
textwrap | 文本包装和填充 | unicodedata | Unicode数据库 |
2.3.2. 列表(List):(P145用列表模拟堆栈(stack.py);P148用列表用作队列(queue.py))
listName = ["value1", "value2", "value3", "value4", ……]
- List 是一个用方括号包括起来的有序元素的集合,可以类比Java中的ArrayList,保存任意对象, 并且可以在增加新元素时动态扩展。可以使用负的索引,它从数据序列的最后一个-1向前数起。
- 可以通过指定2个索引得到 list 的子集,叫做一个“slice”。返回值是一个新的list,它包含了list中按顺序从第一个slice索引开始, 直到不包括第二个slice索引的所有元素。
- List支持+、+=、*运算符和布尔运算符。
列表类型函数(无返回值):
listName.append(“value“) 向 list 的末尾追加单个元素,不论什么数据类型。
listName.insert(<索引>, “value“) 将单个元素插入到 list 中。
listName.extend(["value1", "value2"……]) 用来连接 list。
listName.count(value) 返回value在listName中出现的次数
listName.sort(func=None,key=None,reverse=None) func和key表示以指定方式比较各个元素,reverse为True则以反序排列。默认归并排序,复杂度为O(lg(n!))
listName.reverse() 原地翻转列表
listName.index(“value“) 返回value在listName中首次出现的索引,若无引发异常。
“value” in listName 测试value是否在 listname内,返回True或False。
listName.remove(“value“) 删除value在listName中首次出现的值。
listName.pop() 返回listName最后一个元素,并删除。
△ Python 在布尔环境 (如 if 语句) 中几乎接受所有东西:0 为 false,其它所有数值皆为 true。空串 (“”) 为 false;其它所有字符串皆为 true。空list([])为 false;其它所有list皆为true。空tuple(())为false;其它所有tuple皆为true。空dictionary ({})为 false;其它所有dictionary皆为true;non-empty、non-zero为false。
△ 总结上面一条得出,下列对象的布尔值是False:None、False(布尔类型)、所有值为零的数、0(整数)、0.0(浮点型)、0L(长整型)、0.0+0j(复数)、””空字符串、[]空列表、()(空元组)、{}(空字典)
2.3.3. 元组(Tuple)
tupleName = (“value1“, “value2“, “value3“……)
- Tuple 是用小括号包括起来的有序元素的集合,一旦创建就不能以任何方式改变。只有一个元素的元组需要在元组分隔符里加上一个逗号(,)。可“hash”的对象?
- Tuple 比 list 操作速度快,可以定义为常量集,作为程序的运行中不断地遍历它。
- 对不需要修改的数据进行“写保护”, 可使代码更安全,也可以使用turple,如同拥有隐含的assert语句, 说明数据是常量。Tuple可以作为Dictionary中Key的参数。
- Tuple只有in方法,用于判断Tuple中是否存在某元素。
- 如果必须要改变这些值, 则需要执行 tuple 到 list 的转换 (需要使用一个特殊的函数),Tuple 可以转换成 list, 反之亦然。
△ 拷贝Python对象:浅拷贝和深拷贝
默认拷贝类型(浅拷贝):
1.完全切片操作;2.利用工厂函数;3.使用copy模块的copy函数。
深拷贝:创建一个新的容器对象,包含原有对象元素(引用)全新拷贝的引用,使用copy.deepcopy()函数。
表格 13 与序列类型相关的模块
模块 | 内容 |
array | 一种受限制的可变序列类型,要求所有的元素必须都是相同的类型 |
copy | 提供浅拷贝和深拷贝的能力 |
operator | 包含函数调用形式的序列操作符,比如operator.concat(m,n)就相当于连接操作(m+n) |
re | Perl风格的正则表达式查找(和匹配) |
cStringIO/ | 把长字符串作为文件来操作,比如read()、seek()函数等 |
cStringIO | 把长字符串作为文件来操作,比如read()、seek()函数等,C版的更快一些,但是它不能被继承 |
textwrap | 把作包装/填充文本的函数,也有一个类 |
types | 包含Python支持的所有类型 |
collections | 高性能容器数据类型 |
2.4. 格式化字符串
“%s…%s” % (value1,value2)
- Python 支持格式化字符串的输出,使用方法和C语言中的sprintf 函数一样,最基本的用法是:对于字符串使用%s 的字符串中,对于整数类型使用%d,十进制浮点数类型使用%f,+%.xf表示有正负号的小数点后x位的十进制浮点数,默认情况下是6位精度。
- Python中,字符串连接只能在被连接的每一个都是字符串时起作用,试图将一个字符串同一个非字符串连接会引发一个异常。
表格 14 字符串格式化符号
格式化字符 | 转换方式 |
%c | 转换成字符(ASCII码值,或者长度为一的字符串) |
%r | 优先用repr()函数进行字符串转换 |
%s | 优先用str()函数进行字符串转换 |
%d/%i | 转成有符号十进制数 |
%u | 转成无符号十进制数 |
%o | 转成无符号八进制数 |
%x/%X | 转成无符号十六进制数(x/X代表转换后的十六进制字符的大小写) |
%e/%E | 转成科学计算法(e/E控制输出e/E) |
%f/%F | 转成浮点型(小数部分自然截断) |
%g/%G | %e和%f/%E和%F的简写 |
%% | 输出% |
表格 15 格式化操作符辅助指令
符号 | 作用 |
* | 定义宽度或者小数点精度 |
- | 用作左对齐 |
+ | 在正数前面显示加号(+) |
<sp> | 在正数前面显示空格 |
# | 在八进制数前面显示零(0),在十六进制前面显示0x或者0X(取决于用的是x还是X) |
0 | 显示的数字前面填充0而不是默认的空格 |
% | %%输出一个单一的% |
(var) | 映射变量(字典参数) |
m.n | m是显示的最小总宽度,n是小数点后的位数(如果可用的话) |
2.5. 映射list
[<关于value的表达式> for value in listName]
a. 可以通过对list中的每个元素应用一个函数, 从而将一个list映射为另一个list。
b. 对list的解析并不改变原始的 list。
dictionaryName.keys() 返回一个无序的所有键的 list。
dictionaryName.values() 返回一个所有值的list,以 keys 返回的 list 顺序输出dictionaryName.items() 返回一个形如 (key, value) 的 tuple 的 list。
2.6. 连接list与分割字符串
(*).join(listName) 连接一个list中的元素为一个字符串,*表示各元素间连接的符号。
anystring.split(delimiter,num) 分隔一个字符串,其中delimiter为字符串分隔符,num为可选参数,表示分割的次数。不带参数的 split 按照空格进行分割。
三、Python过程语句
3.1. if语句
if expression:
if_suite
elif expression2:
elif_suite
……
else:
else_suite
条件表达式(“三元操作符”):X if C else Y
避免“悬挂”else:P191
C语言中,else与最近的if搭配,属于内部的if,C编译器编译时会忽略额外的空白;而Python使用缩进使用强制使代码正确对齐,让程序员来决定else属于哪一个if。但是在大块的代码嵌入到类似的框架中时,会产生很多错误。
3.2. while循环
while expression:
suite_to_repeat
3.3. for循环
for iter_var in iterable:
suite_to_repeat
- 迭代字符串是,迭代变量只会包含一个字符。迭代序列的三种方法:序列项、序列索引、使用项和索引。while和for语句中可以使用else语句。
break语句、continue语句、pass语句
- 迭代器和iter()函数:返回一个迭代器
Python中可迭代的对象:列表、字典、文件。新的三个内建字典方法定义迭代:~.iterkeys(),~.itervalues(),~.iteritems()。一个实现了__iter__()和next()方法的类可作为迭代器。
- 列表解析(P206矩阵样例,磁盘文件样例)
[expr for iter_var in iterable]
[expr for iter_var in iterable if cond_expr]
- 生成器表达式
特定的函数,允许返回一个值,然后“暂停”代码的执行,稍后恢复。并不真正创建数字列表,而是返回一个生成器,在每次计算出一个条目后,将它“产生”(yield)出来。使用了“延迟计算”(lazy evaluation),在使用内存上更有效。(P207例子)
- range(start,end,step=1) 返回值为一个列表
简略形式:range(end) start默认为0
range(start,end)
xrange类似range()不在内存中创建列表完整拷贝,大范围列表是用在for循环中。
与序列相关的内建函数:sorted(),reversed(),enumerate(),zip(),P198例子
四、文件对象
4.1. 文件内建函数(open()和file())
fileObject = open(file_name, access_mode=‘r’,buffering=-1)
a. open 方法可以接收三个参数:文件名,模式,和缓冲区参数。如果没有指定,文件以文本方式打开。(print open.__doc__ 会给出所有可能模式的很好的解释。)文件的打开主要有三种模式:”Append”(打开模式简写a)模式在写入数据时追加到文件尾,”write”(打开模式简写w)模式在写入数据时将覆盖文件的原有内容,”Read_Only”(打开模式简写r)模式仅用于读取文件内容。
b. open 函数返回一个对象,对象mode属性返回文件打开模式,name属性返回打开的文件名。
c. 工厂函数file()同open()。
d. 文件对象的newlines属性会记录文件的行结束符。UNS(Universal NEWLINE Support通用换行符)
表格 16 文件对象的访问模式
文件模式 | 操作 | 文件模式 | 操作 |
r | 读模式 | rU或U | 读模式打开,同时提供通用换行符 |
w | 写模式(必须清空) | a | 追加模式(从EOF开始,必要时创建新文件) |
r+ | 读写模式 | w+ | 读写模式(参见w) |
a+ | 读写模式(参见a) | rb | 二进制读模式 |
wb | 二进制写模式 | ab | 二进制追加模式 |
rb+ | 二进制读写模式(参见r+) | wb+ | 二进制读写模式(参见w+) |
ab+ | 二进制读写模式(参见a+) |
4.2. 文件对象内建方法
4.2.1. 输入
read() 直接读取字节到字符串中
readline() 读取打开文件的一行,返回包含行结束符的字符串
readlines() 读取所有(剩下的)行,把它们作为一个字符串列表返回
△ 保留行结束符:使用输入方法从文件读取行时,需要手动删除行结束符;使用输出方法时需要手动加入行结束符。
△ 行分隔符和其他文件系统的差异:在POSIX系统上,行分隔符是换行符NEWLINE(\n)字符,旧的MacOS下是RETURN(\r),DOS和Wind32系统下结合使用了两者(\r\n)。路径分隔符(POSIX使用“/”;DOS和Windows使用“\”;旧版的MacOS使用“:”)用来分隔文件路径名、标记当前目录和父目录。
表格 17 跨平台开发的os模块
os模块属性 | 描述 |
linesep | 用于在文件中分隔行的字符串 |
sep | 用来分隔文件路径名的字符串 |
pathsep | 用于分隔文件路径的字符串 |
curdir | 当前工作目录的字符串名称 |
pardir | (当前工作目录的)父目录字符串名称 |
4.2.2. 输出
write() 把含有文本数据或二进制数据块的字符串写入文件中
4.2.3. 文件内移动
seek() 移动文件指针到不同位置,0从文件头,1从当前位置,2从文件尾
tell() 返回当前文件指针位置,从文件起始算起,单位为字节
文件迭代:for eachLine in f:
4.2.4. 其他
close() 关闭文件,结束访问
fileon() 返回打开文件的描述符,整形数据
flush() 直接把内部缓冲区中数据立刻写入文件
isatty() 布尔函数,文件是类atty设备时返回True
truncate() 将文件截取到当前文件指针位置,或者给定size以字节为单位
4.3. 标准文件sys模块中stdin,stdout,stderr
4.4. sys模块通过sys.argv属性提供了对命令行参数的访问,命令行参数是调用某个程序是除程序名以外的其他参数。C语言中argv是从命令行上输入的各个参数组成的字符串数组,argc是输入的参数的个数。Python中:sys.argv是命令行参数的列表,len(sys.argv)是命令行参数的个数。相关模块getopt,optparse
4.5. 文件系统
表格 18 os模块的文件/目录访问函数
函数 | 描述 |
文件处理 | |
mkfifo()/mknod( | 创建命名管道/创建文件系统节点 |
remove()/unlink() | 删除文件 |
rename()/renames() | 重命名文件 |
stat() | 返回文件信息 |
symlink() | 创建符号链接 |
utime() | 更新时间戳 |
tmpfile() | 创建并打开(‘w+b’)一个新的临时文件 |
walk() | 生成一个目录树下的所有文件名 |
目录/文件夹 | |
chdir()/fchdir() | 改变当前工作目录/通过一个文件描述符改变当前工作目录 |
chroot() | 改变当前进程的根目录 |
listdir() | 列出指定目录的文件 |
getcwd()/getcwdu() | 返回当前工作目录/功能相同,但返回一个Unicode对象 |
mkdir()/removedirs() | 创建目录/创建多层目录 |
rmdir()/removedirs() | 删除目录/删除多层目录 |
访问/权限 | |
access() | 检验权限模式 |
chmod() | 改变权限模式 |
chown()/lchown() | 改变owner和group ID/功能相同,但不会跟踪链接 |
umask() | 设置默认权限模式 |
文件描述符操作 | |
open() | 底层的操作系统open(对于文件,使用标准的内建open()函数 |
read()/write() | 根据文件描述符读取/写入数据 |
dup()/dup2() | 复制文件描述符号/功能相同,但是是复制到另一个文件描述符 |
设备号 | |
makedev() | 从major和minor设备号创建一个原始设备号 |
major()/minor() | 从原始设备号获得major/minor设备号 |
表格 19 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() | 两个路径名是否指向同一个文件 |
4.6. 永久存储模块
将比基本类型复杂的对象转换为一个二进制数据集合,marshall模块只能处理简单的Python对象,pickle可以处理递归对象,被不同地方多次引用的对象,以及用类自定义的类和实例。shelve模块
相关模块P229表9.7
文件相关模块如下表:
表格 20 文件相关模块
模块 | 内容 |
base64 | 提供二进制字符串和文本字符串间的编码/解码操作 |
binascii | 提供二进制和ASCII编码的二进制字符串间的编码/解码操作 |
bz2 | 访问BZ2格式的压缩文件 |
csv | 访问csv文件(逗号分隔文件) |
filecmp | 用于比较目录和文件 |
fileinput | 提供多个文本文件的行迭代器 |
getopt/optparse | 提供了命令行参数的解析/处理 |
glob/fnmatch | 提供UNIX样式的通配符匹配的功能 |
gzip/zlib | 读写GUN zip(gzip)文件(压缩需要zlib模块) |
shutil | 提供高级文件访问功能 |
c/StringIO | 对字符串对象提供类文件接口 |
tarfile | 读写tar归档文件,支持压缩文件 |
tempfile | 创建一个临时文件(名) |
uu | uu格式的编码和解码 |
zipfile | 用于读取ZIP归档文件的工具 |
五、异常处理
异常是因为程序出现了错误而在正常控制流以外采取的行为。
5.1. try-except-else-finally语句
try:
try_suite
except Exception1:
suite_for_Exception1
……
else:
no_exceptions_detected_suite
finally:
always_execute_suite
a. Python 使用 try…except 来处理异常,使用 raise 来引发异常。 Java 和 C++ 使用 try…catch 来处理异常,使用 throw 来引发异常。
b. 使用不存在的字典关键字将引发 KeyError 异常,搜索列表中不存在的值将引发 ValueError异常,调用不存在的方法将引发AttributeError 异常。引用不存在的变量 将引发 NameError 异常。未强制转换就混用数据类型 将引发 TypeError 异常。
c. 一旦异常被处理了,处理通常在 try…except 块之后的第一行继续进行。注意这一行将总是打印出来,无论异常是否发生。
5.2. 触发异常
raise语句:raise [SomeException [, args[, traceback]]]
- 参数一,是触发异常的名字,必须是一个字符串、类或实例;若有其他参数,则须提供SomeException.Python所有标准异常。见附录…………
- 参数二,单一字符串来指示错误原因,元组则组成是一个错误字符串,一个错误编号,还可能是一个错误的地址。
- 参数三,当异常触发时新生成的一个用于异常-正常化(exception-normally)的跟踪记录对象)。
5.3. 断言
assert expression [, arguments]
5.4. sys模块中exc_info()函数可以获取异常信息,返回一个三元组(3-tuple)的信息。
exc_type:异常类
exc_value:异常类的实例
ex_traceback:跟踪记录对象
六、函数和函数式编程
6.1. Python函数详解
declaration /definition def foo():print ‘bar’
function object /reference foo
function cal /invocation foo()
△ P269参数组
a. Python函数可以返回一个值或者对象,默认为元组,若加括号则为列表
b. 存储元组返回值的方式3种
c. 函数调用中的关键字参数、默认参数
d. Python支持内部/内嵌函数,除在函数体内,任何地方都不能对其进行调用
e. 装饰器:引入日志;增加计时逻辑来检测性能;给函数加入事务能力P277例11.2
6.2. 可变长度参数
Formal Arguments形参集合(位置和默认):
使用*和**来指定元组和字典的元素作为非关键字及关键字参数。
a. 非关键字可变长参组(元组):位于最后,元组保存所有传递给函数的“额外”的参数,如果没有则为空。
b. 关键字变量参数(字典):使用双星号(**)。
c. 调用带有可变长参数对象:定义对象,在函数调用中传递的对象加上*和**。
6.3. 测试函数(例如:)
def testit(func, *nkwargs,**kwargs)
try:
retval=func(*nkwargs,**kwargs)
result=(True,ritual)
except Exception,diag
result=(False,str(diag))
return result
6.4. 函数式编程
- 匿名函数与lambda:lambda[args1[,args2,…argsN]]:ecpression使用lambda关键字创建匿名函数。用合适的表达式调用一个lambda生成一个可以像其它函数一样使用的函数对象。可被传递给其他函数,用额外的引用别名化,作为容器对象以及作为可调用对象被调用。
- 内建函数apply(),filter(),map(),reduce():P288表11.2
a) from random import randict as ri
print [n for n in [ri(1,99) for I in range(9)]if n%2]
b) map(lambda x,y:(x+y,x-y),[1,3,5],[2,4,6])
c) reduce((lambda x,y:x+y),range(5))
函数式编程的内建函数如下表:
表格 21 函数式编程的内建函数
内建函数 | 描述 |
apply(func[,nkw] [,kw]) | 用可选的参数来调用func,nkw为非关键字参数,kw为关键字参数;返回值是函数调用的返回值(逐渐淘汰) |
filter(func,seq) | 调用一个布尔函数func来迭代遍历每个seq中的元素;返回一个使func返回值为true的元素列表(部分被摒弃) |
map(func,seq1[, seq2…]) | 将函数func作用于给定序列(s)的每个元素,并用一个列表来提供返回值;如果func为None,func表现为一个身份函数,返回一个含有每个序列中元素集合的n个元组列表 |
reduce(func,seq [,init]) | 将二元函数作用于seq序列的元素,每次携带一对(先前的结果以及下一个序列元素),连续地将现有的结果和下一个值作用在获得的随后的结果上,最后减少我们的序列为一个单一的返回值;如果初始值init给定,第一个比较会是init和第一个序列元素而不是序列的头两个元素 |
- 偏函数应用:Currying能泛化成为偏函数引用(partial function application,PFA),这种函数将任意数量(顺序)的参数的函数转化为另一个带剩余参数的函数对象。
from functions import partial
basetwo = partial(int,base=2)
6.5. 变量的作用域
局部作用域内为了明确引用全局变量使用关键字global。
闭包
def counter(start_at=0):
count=[start_at]
def incr():
count[0]+=1
return count[0]
return incr
6.6. 递归
6.7. 生成器
import generators form __future__
yield ~送回生成器[send()],生成器退出[close()]
def counter(start_at=0):
count=start_at
while True:
val=(yield count)
if val is not None
count=val
else count+=1
七、 模块(自我包含并且有组织的代码片段)
7.1. 名称空间:名称(标识符)到对象的映射
a. 向名称空间添加名称操作过程涉及绑定标识符到指定对象的操作(引用计数加1);
b. Python解释器加载名称空间顺序:内建~,执行模块的全局~,(两个活动~);执行期间调用函数将创建第三个名称空间(局部~),通过globals()和locals()内建函数判断属于哪个~;
c. __builtins__模块包含__builtin__模块(包含内建函数,异常和其他属性)和内建名称空间中内建名字的集合;
d. 作用域:指出了从用户代码的哪些物理位置可以访问名称(标识符);
e. 无限制的名称空间:可以在任何需要放置数据的地方获得一个名称空间。
完整授权名称(fully qualified)、路径搜索(查找某个文件的操作)、搜索路径(查找一组目录);默认搜索路径:sys.path。
7.2. 导入模块(遵循作用域原则)
模块导入方法:①import语句;②form-import语句;③多行导入(行尾使用\符号);④扩展的import语句(as)。
a. 模块导入几点注意:
a) 限制使from modual import *“污染当前名称空间。两种场合建议使用:1.目标模块属性多,反复键入模块名行不方便;2.交互解释器下,减少输入次数。
b) sys.modual.keys()查看当前载入到解释器的模块组成字典的模块名;
c) 阻止属性导入:使用from modual import*时,可以给不想导入的属性名称前加下划线(_),但导入整个模块或显示地导入某个属性时不起作用;
d) 不区分大小写的导入(?PYTHONCASEOK环境变量)
e) 模块头部加入一个额外的编码表示说明可以让导入者使用指定的编码解析你的模块,例:
#!user/bin/envpython
#_*_coding:UTF-8-**
f) 导入循环?
g) 模块执行(命令行、shell、execfile()、模块导入、解释器的-m选项等);相关模块:modulefinder, pkgutil, zipimport
b. 只从模块导入名字会成为局部名称空间的一部分,可能覆盖一个已经存在的具有相同名字的对象。使用import和完整标识符名称(名字属性标识)解决。
c. from __future__ import new_future“导入”新特性,用户可以尝试新特性或特性变化,以便在特性固定下来的时候修改程序。
d. 警告框架:①应用程序(员)接口(Application programmer’s interface API);②警告过滤器(警告会有一个默认的输出显示到sys.stderr。命令行也可控制警告过滤器,使用-w选项)
e. 从zip文件中导入模块:把zip文件当做目录处理,在文件中搜索模块。
7.3. 模块内建函数
a. __import__(modual_name[,globals[,locals[,fromlist]]])可以使用自定义导入算法覆盖原函数
b. globals()和locals()返回调用者全局和局部名称空间的字典,全局名称空间下两函数返回值相同。
c. reload(modual)重新导入一个已经导入的模块(全部且成功导入)
7.4. 包
有层次的文件目录结构,定义了一个由模块和子包组成的Python应用程序执行环境。和模块相同,也使用句点属性标识来访问他们的元素,使用标准的import和from –import语句导入包中模块。
P321引入包的作用
八、Python面向对象
8.1. Python对象概述
a. Python使用对象模型来存储数据,构造任何类型的值都是一个对象,所有Python对象都有以下三个特性:身份(id()查看,被认为是该对象的内存地址)、类型(type()查看)和值。所有Python类型的根和所有Python标准累的 默认元组(metaclass)即type。对象的身份比较:obj1 is (not) obj2或id(obj1) == id(obj2)。Python仅缓存简单整型。
b. Python内部对象
a) 代码:编译过的Python源代码片段,compile()执行exec命令或eval()内建函数,用户自定义函数核心。
b) 帧:标识Python的执行栈帧,包含Python解释器运行时需要知道的所有信息。
c) 跟踪记录:异常发生时,一包含针对异常的栈跟踪信息的跟踪记录对象被创建。
d) 切片对象:
e) 省略对象:用于扩展切片语法中起记号作用,表示省略号。
f) XRange对象:
c. 工厂函数:即类对象,当调用时,实际是创建了一个类实例。
8.2. 类属性
a. Python不支持纯虚函数或者抽象方法,这些都是强制在子类中定义方法。作为替代方法,可以简单地在基类方法中引发NotImplementedErrer异常,获得类似效果。
查看类属性:①使用dir()内建函数;②访问类的字典属性__dict__(所有类都具备的特殊属性之一)。__doc__是类的文档字符串,不被派生类继承。
表格 22 特殊类属性
C.__name__ | 类C的名字(字符串) |
C.__doc__ | 类C的文档字符串 |
C.__bases__ | 类C的所有父类构成的元组 |
C.__dict__ | 类C的属性 |
C.__module__ | 类C定义所在的模块 |
C.__class__ | 实例C对应所在的类(仅新式类中) |
b. 命名类属性和方法:①类名以大写字母开头,数据属性听起来应当是数据值的名字,方法名应当指出对应对象或值的行为;②数据值使用名词作为名字,方法使用谓词(动词加对象)。
8.3. 类实例
a. __init__()构造器方法
b. __new__()构造器方法 (见13.11.3)
c. __del__()解构器方法,直到该实例对象所有引用都被清除掉后才会执行(P343 DEL方法使用总结)
△ 跟踪实例:使用静态成员记录实例个数,显式加入一些代码进入类定义或__init__()和__del__()中
8.4. 实例属性(能够中“运行时”创建实例属性)
a. 构造器中首先设置实例属性;默认参数提供人都市里安装;__init__()应当返回None;内建实例属性使用dir()查看,不存在__dict__属性;给一个与类属性同名的实例属性赋值,会有效地“隐藏”类属性,若类属性可变则无法删除修改后实例属性,修改类属性使用类名而不是实例名。
b. 使用dir()查看所有实例属性(同样可用于查看类属性);
c. 特殊实例属性:I.__class__实例化I都类,I.__dict__I都属性;
d. 可修改类和实例中__dict__属性,但要重载__setattr__方法。
8.5. 绑定与方法调用()
调用绑定方法:self参数不需要明确地传入;
调用非绑定方法:必须传递self参数。
8.6. 静态方法和类方法
a. 使用staticmethos()和classmethos()内建函数进行转换;
b. 使用函数修饰符(@staticmethos和@classmethos)。
8.7. 继承
a. 使用类与其他数据类型及逻辑执行流混合使用都方法:组合、子类和派生类;
class SubClassName(ParentClass1 [, ParentClass2,...])
‘class_suite’
b. 文档字符串对类、函数/方法、模块来说都是唯一的,特殊属性__doc__不会从基类中继承过来;__base__类属性,对任何(子)类,是一个包含其他父类(parent)的集合的元组,没有父类的类的属性值为空;
c. 使用super()内建函数显式地调用父类方法;重写__init__不会自动调用基类的__init__; super(子类名,self).__init__() <=> 基类名.__init__(self)
d. 从标准类型派生:
不可变类型class RoundFloat(float):
def __new__(cls,val):
return super(RoundFloat,cls).__new__(cls,round(val,2)
可变类型 class SortedKeyDict(dict):
def keys(self):
return Sorted(super(SortedKeyDict,self).keys())
- 多重继承(要点:1.找到合适都属性;2.重写方法时,如何调用对应父类方法,“以发挥它们的作用”,同时在子类中处理好自己的义务。)
a) 方法解释顺序(MRO):经典类使用深度优先,从左至右的查找顺序;新式类使用广度优先,首先查找同胞兄弟。
(新式类属性__mro__显示查找都顺序)
b) 棱形效应引起MRO问题
8.8. 类、实例和其他对象都内建函数
表格 23 类、实例和其他对象都内建函数
issubclass(sub, sup) | 如果类sub是类sup的子类,则返回True,反之为False |
isinstance(obj1, obj2) | 如果实例obj1是类obj2或者obj2子类的一个实例;或者如果obj1是obj2的类型,则返回True,反之为False |
hasattr(obj,attr) | 如果obj有属性attr(用字符串给出),返回True,反之为False |
getattr(obj,attr[,default]) | 获取obj的attr属性;与返回obj.attr类似;如果attr不是obj的属性,则返回默认值或引发AttributeError异常 |
setattr(obj,attr,val) | 设置obj的attr属性值为val,否则创建属性 |
delattr(obj,attr) | 从obj中删除属性attr(以字符串给出) |
dir(obj=None) | 返回obj的属性的一个列表;如果没有给定obj,dir()则显示局部名字空间中的属性,即locals().keys() |
super(type,obj=None) | 返回一个表示父类类型的代理对象;如果没有转入obj,则返回的super对象是非绑定的;反之如果obj是一个type,issubclass必为True;否则isinstance就必为True |
vars(obj=None) | 返回obj的属性及其值的一个字典;如果没有给出obj,vars()显示局部名字空间字典(属性及其值),即locals() |
8.9. 用特殊方法定制类
示例:例13.2 P371 roundFloat2.py、P374 例13.3 time60.py、例13.4 randSeq.py
a. 迭代器
a) RandSeq(RANDom SEQuence的缩写)(无损地读取一个序列,不会越界,永远不会引发StopIteration异常);
b) AnyIter(ANY number of items ITERator)(同时给出一个安全标示符(safe)来创建这个对象,为真则在遍历完这个迭代器前,返回所获取的任意条目;若为假,则在用户请求过多条目时,引发异常。示例P376 例13.5 anyIter.py
b. 多类型定制(NumStr)示例P378 例13.6 numstr.py
表格 24 定制类的特殊方法
特殊方法 | 描述 |
基本定制型 | |
C.__init__(self[,arg1,...]) | 构造器(带一些可选参数) |
C.__new__(self[,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) and C.__le__(self,obj) | 小于/小于或等于;对应<及<=操作符 |
C.__gt__(self,obj) and C.__ge__(self,obj) | 大于/大于或等于; |
C.__eq__(self,obj) and C.__ne__(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) | (描述符)设置属性 |
C.__delete__(self,attr) | (描述符)删除属性 |
定制类/模拟类型 | |
数值类型:二进制操作符 | |
C.__*add__(self,obj) | 加;+操作符 |
C.__*sub__(self,obj) | 减;-操作符 |
C.__*mul__(self,obj) | 乘;*操作符 |
C.__*div__(self,obj) | 除;/操作符 |
C.__*truediv__(self,obj) | True除;/操作符 |
C.__*floordiv__(self,obj) | False除;//操作符 |
C.__*mod__(self,obj) | 取模/取余;%操作符 |
C.__*divmod__(self,obj) | 除和取模;内建divmod() |
C.__*pow__(self,obj[,mod]) | 乘幂;内建pow();**操作符 |
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) | 绝对值;内建abs() |
C.__invert__(self) | 按位求反;~操作符 |
数值类型:数值转换 | |
C.__complex__(self,com) | 转为complex(复数);内建complex() |
C.__int__(self) | 转为int;内建int() |
C.__long__(self) | 转为long;内建long() |
C.__float__(self) | 转为float;内建float() |
数值类型:基本表示法(String) | |
C.__oct__(self) | 八进制表示;内建oct() |
C.__hex__(self) | 十六进制表示;内建hex() |
数值类型:数值压缩 | |
C.__coerce__(self,num) | 压缩成同样的数值类型;内建coerce() |
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) | 散列(hash)函数值 |
C.__getitem__(self,key) | 得到给定键(key)的值 |
C.__setitem__(self,key,val) | 设置给定键(key)的值 |
C.__delitem__(self,key) | 删除给定键(key)的值 |
C.__missing__(self,key) | 给定键如果不存在字典中则提供一个默认值 |
8.10. 私有化
- Python的默认属性都是“公开的”;
- 双下划线(__):私有性的初步形成()
- 单下划线(_):简单的模块级私有化只需要中属性名前使用一个单下划线字符,防止模块的属性用”from mymodule import *”加载,这种严格是基于作用域,也适用于函数。
8.11. 授权(P386 例13.7 twrapme.py)
8.12. 新式类的高级属性
- Python中工厂函数:init(),long(),float(),complex(),str(),unicode(),list() tuple(),type();(新加入)basestring(),dict(),bool(),set(),frozenset() object(),classmethod(),staticmethod(),super(),property(),file()
- __slots__类属性:可替代属性__dict__,是一个类变量,由一序列对象组成,由所有合法标识符构成的实例属性的集合来表示,可以是元组、列表或可迭代对象或简单的字符串,试图创建非__slots__中名字的实例属性将导致AttributeError异常。
- __getattribute__()特殊方法?P394 例13.9 descr.py
- 描述符
a) __get__(),__set__()和__delete__()特殊方法;
b) 优先级别:类属性->数据描述符->实例属性->非数据描述符;
c) 属性和property()内建函数 –> 默认为__getattr__()?
- 元类和__metaclass__(元类[MetaClasses]赋予你如何创建类的控制权,传统类的元素是types.ClassType)P402 例13.10 meta.py
表格 25 与类相关的模块
模块 | 说明 |
UserList | 提供一个列表对象的封装类 |
UserDict | 提供一个字典对象的封装类 |
UserString | 提供一个字符处对象的封装类;包括一个MutableString子类,又需要还可提供有关功能 |
types | 定义所有Python对象的类型在标准Python解释器中的名字 |
operator | 标准操作符的函数接口 |
九、执行环境
9.1. 可调用对象(Python有4种可调用对象:函数、方法、类和一些类的实例)
9.1.1. 函数
a. 内建函数(BIF):用C/C++写的,编译后放入Python解释器,作为第一(内建)名称空间的一部分加载进系统。这些函数中__bulitin__模块中,作为__builtins__模块导入到解释器中。
表格 26 内建函数属性
属性 | 描述 |
bif.__doc__ | 文档字符串(或None) |
bif.__name__ | 字符串类型的文档名字 |
bif.__self__ | 设置为None(保留给内建方法) |
bif.__module__ | 存放bif定义的模块名字(或None) |
b. 用户定义的函数(UDF):定义在模块最高级,作为全局名称空间都一部分装载到系统中。
表格 27 用户自定义函数属性
属性 | 描述 |
udf.__doc__ | 文档字符串(也可用udf.func_doc) |
udf.__name__ | 字符串类型的函数名字(也可用udf.func_name) |
udf.func_code | 字节编译的代码对象 |
udf.func_defaults | 默认的参数元组 |
udf.func_globals | 全局名称空间字典;和从函数内部调用globals(x)一样 |
udf.func_dict | 函数属性的名称空间 |
udf.func_doc | 见上 |
udf.func_name | 见上 |
udf.func_closure | 包含自由变量的引用的单元对象元组 |
c. lambda表达式(名为“<lambda>”的函数)
9.1.2. 方法
a. 内建方法(BIM)
如下是内建方法的属性:
表格 28 内建方法的属性
属性 | 描述 |
bim.__doc__ | 文档字符串 |
bim.__name__ | 字符串类型的函数名字 |
bim.__self__ | 绑定的对象 |
b. 用户定义的方法(UDM):包含在类定义中,只有标准函数都包装,仅有定义它们都类可以使用。
表格 29 用户自定义方法的属性
属性 | 描述 |
udm.__doc__ | 文档字符串(与dum.im_func.__doc__相同 |
udm.__name__ | 字符串类型的方法名字(与udm.im_func.__name__相同 |
udm.__module__ | 定于udm的模块的名字(或none) |
udm.im_class | 方法相关联的类(如果是非绑定,则为要求udm的类 |
udm.im_func | 方法的对象 |
udm.im_self | 如果绑定的话为相关联的实例,如果非绑定则为none |
9.1.3. 类:“调用”类的结果便是创建了实例
9.1.4. 类的实例:Python给类提供了名为__call__的特殊方法,允许程序员创建可调用对象(实例),默认情况没有实现该方法,即大多数实例都是不可调用的。
9.2. 代码对象(每个可调用物的核心都是代码对象,可以作为函数或者方法调用的一部分来执行,也可用exec语句或内建函数eval()来执行。整体上,一个Python模块的代码对象是构成该模块全部代码。
9.3. 可执行对象声明和内建函数
P421 例14.1 loopmake.py、P425 例14.2 funcAttrs.py
表格 30 可执行的对象声明和内建函数
内建函数和语句 | 描述 |
callable(obj) | 如果obj可调用,返回True,否则返回FALSE |
compile(string, file, type) | 从type类型中创建代码对象;file是代码存放的地方 |
eval(obj,globals=blobals(), locals=locals()) | 对obj进行求值,obj是已编译为代码对象的表达式,或是一个字符串表达式;可以给出全局或者/和局部的名称空间 |
exec obj | 执行obj、单一的Python语句或者语句的集合,也就是说格式是代码对象或者字符串;ojb也可以是一个文件对象 |
input(prompt=”) | 等同于eval(raw_input(prompt=”)) |
9.4. 执行其他(Python)程序
a. 导入(在定义模块的执行语句前加入语句if __name– = ‘__main__’;
b. execfile() => execfile(filename,globals=blobals(),locals=locals());
c. 将模块作为脚本执行(可以使用命令行从工作目录中调用脚本$ myScript.py # or $ python myScript.py)
9.5. 执行其他(非Python)程序
表格 31 为外部程序执行提供的os模块(△代表Unix下,■代表Windows下)
模块函数 | 描述 |
system(cmd) | 执行程序cmd(字符串),等待程序结束,返回退出代码(windows下始终为0) |
fork() | 创建一个和父进程并行的子进程(通常是和exec()一起使用);返回两次…一次给父进程一次给子进程△ |
execl(file,arg0,arg1,…) | 用参数arg0、arg1等执行文件 |
execv(file,arglist) | 除了使用参数向量列表,其他的和execle相同 |
execle(file,arg0,arg1,…env) | 和execl相同,但是提供环境变量字典env |
execve(file,arglist,env) | 除了带有参数向量列表,其他和execl相同 |
execlp(cmd,arg0,rarg1,…) | 与execl相同,但是在用户的搜索路径下搜索完全的文件路径名 |
execvp(cmd,arglist) | 除了带有参数向量列表,其他和execlp相同 |
execlpe(cmd,arg0,arg1,…env) | 和execlp相同,但是提供了环境变量字典 |
execvpe(cmd,arglist,env) | 和execvp相同,但是提供了环境变量字典 |
spawn(mode,file,args[,env]) | spawn()家族在一个新的进程中执行路径,args作为参数,也许还有环境变量的字典env;模式(mode)是个显示不同操作模式的魔术 |
wait() | 等待子进程完成(通常和fock和exec()一起使用△ |
waitpid(pid,options) | 等待指定的子进程完成(通常和fock和exec()一起使用△ |
popen(cmd,mode=’r’, buffering=-1) | 执行字符串cmd,返回一个类文件对象作为运行程序通信句柄,默认为读取模式和默认系统缓冲startfileb(path) |
startfile(path) | 用关联的应用程序执行路径■ |
- a. os.system()
- b. os.popen()
- c. os.fork()、os.exec()、os.wait()
- d. os.spawn()
- e. subprocess模块
表格 32 各种文件执行函数
文件对象属性 | 描述 |
os/popen2.popen2() | 执行文件、打开文件、从新创建的运行程序读取(stdout),或者向该程序写(stdin) |
os/popen2.popen3() | 执行文件、打开文件、从新创建的运行程序读取(stdout和stderr),或者向该程序写(stdin) |
os/popen2.popen4() | 执行文件、打开文件、从新创建的运行程序读取(结合stdout,stderr),或者向该程序写(stdin) |
commands.getoutput() | 在子程序中执行文件,以字符串返回所有的输出(Unix下) |
subprocess.call() | 创建subprocess的便捷函数。Popen等待命令完成,然后返回状态代码;与os.system()类似,是较灵活的替代方案 |
9.6. 受限执行
在Python历史的某个时期,存在着使用了rexec和bastion模块的限制执行的概念。第一个模块允许沙盒(sandbox)中的执行代码修改内建对象。第二个模块用来过滤属性和包装你的类。但由于一个显著的缺点和弥补安全漏洞的困难,这些模块便被废弃了。
9.7. 结束执行
干净的执行表示当所有模块最高级的语句执行完毕后的退出,当遇到某种致命的错误或不满足继续执行的条件的时候,Python会提前退出。可以通过异常和异常处理,或者建造一个“清扫器”方法,把代码的主要部分放在if语句中,在没有错误的情况下执行,因而可以让错误的情况“正常地”终结。
- sys.exit() and SystemExit
当调用sys.exit()时,会引发systemExit()异常。除非对异常进行监控,异常通常不会被捕捉到或处理的,解释器会用给定的状态参数退出,默认为0,exit()的任何整型参数都会以退出状态返回给调用者。sys.exit()经常用在命令调用的中途发现错误之后。
- sys.exitfunc()
sys.exitfunc()默认是不可用的,可以修改它以提供额外的功能。在调用exit()退出解释器之前用到这个函数,如果sys.exitfunc已经被先前定义的exit函数覆盖了,则把这段代码作为exit()函数的一部分执行。通常exit函数用于执行某些类型的关闭活动,比如关闭文件和网络连接,最好用于完成维护任务,比如释放先前保留的系统资源。
- os._exit()函数
os模块中的_exit()函数不是在一般应用中使用(平台相关,只是用特定的平台,比如基于Unix的平台,以及Win32平台)。语法是os._exit(status),不执行任何清理便立即退出Python,状态参数是必需的。
- os.kill() Function
os模块的kill()函数模拟传统的unix函数来发送信号给进程。kill()参数是进程标识数(PID)和想要发送的进程的信号。发送的典型信号为SIGINT、SIGQUIT、或更彻底地,SIGKIL来使进程终结。
9.8. 各种操作系统接口
表格 33 各种OS模块属性(△也适用于win32)
模块属性 | 描述 |
unname() | 获得系统信息(主机名、操作系统版本,补丁级别、系统架构等) |
getuid()/setuid(uid) | 获取/设置现在进程都真正都用户ID |
getpid()/getppid() | 获取真正的现在/父进程ID(PID)△ |
getgid()/setgid(gid) | 获取/设置现在进程都群组ID |
getsid()/setsid() | 获取会话ID(SID)或创建和返回新的SID |
umask(mask) | 设置现在的数字unmask,同时返回先前的那个(mask用于文件许可)△ |
getenv(ev)/putenv(ev,value), environ | 获取和设置环境变量ev的值;os.envion属性是描述当前所有环境变量的字典△ |
geteuid()/setegid() | 获取/设置当前进程的有效用户ID(GID) |
getegid()/setegid() | 获取/设置当前进程都有效组ID(GID) |
getpgid(pid)/setpgid(pid, pgrp) | 获取和设置进程GID进程PID;对于get,如果pid为0,便返回现在进程的进程GID |
getlogin() | 返回运行现在进程的用户登录 |
times() | 返回各种进程时期的元组△ |
strerror(code) | 返回和错误代码对应的错误信息△ |
getloadavg() | 返回代表在过去1,5,15分钟内的系统平均负载值的元组 |
表格 34 相关模块
模块 | 描述 |
atexit | 注册当Python解释器退出时的执行句柄 |
popen2 | 提供额外的在os.popen之上的功能:提供通过标准文件和其他进程交互的能力;对于Python2.4及以上版本,使用subpross() |
commands | 提供额外的在os.system之上的功能:把所有的程序输出保存在返回的字符串中(与输出到屏幕相反);对于2.4及以上版本,使用subpross |
getopt | 在这样的应用程序中的处理选项和命令行参数 |
site | 处理site-specific模块或包 |
platform | 底层平台和架构的属性 |
subprocess | 管理(计划替代旧的函数和模块,比如os.system()、os.spawn()、os.popen()、popen2.*和command.*) |