pthon核心编程读书笔记:知识点摘录与总结(方便理解和快速记忆)代码王子

可升级:Python提倡简洁的代码设计、高级的数据结构和模块化的组件,确保灵活性、

扩展性:兼容扩展c和java

易读写,易维护

健壮性:Python提供了“安全合理”的退出机制,Python由于错误崩溃,解释程序就会转出一个“堆栈跟踪”,那里面有可用到的全部信息,包括你程序崩溃的原因以及是那段代码(文件名、行数、行数调用等等)出错了。这些错误被称为异常。如果在运行时发生这样的错误,Python能够监控这些错误并进行处理。描述错误的类型和位置,还能指出代码所在模块。

快速原型开发工具:Python标准库是很完备的,如果你在其中找不到所需,那么第三方模块或包就会为你完成工作提供可能。

内存管理是由Python解释器负责。C或者C++最大的弊病在于内存管理是由开发者负责的,会分散精力

类似于Java,Python是字节编译的,可以生成一种近似机器语言的中间形式,提升性能。

Unix中,可执行文件通常会将Python安装到/usr/local/bin子目录下,而库文件则通常安装在/usr/local/lib/python2.x子目录下

运行Python

命令行和脚本模式(解释器执行)

命令行选项:

-d提供调试输出

-O生成优化的字节码(生成.pyo文件)

-S不导入site模块以在启动时查找Python路径

-v冗余输出(导入语句详细追踪)

-mmod将一个模块以脚本形式运行

-Qopt除法选项(参阅文档)

-ccmd运行以命令行字符串形式提交的Python脚本

file从给定的文件运行Python脚本(参阅后文)

脚本头部添加“#!/usr/local/bin/python”正确的安装位置,可以找到python,否则给出错误提示。或者借用unix下env环境变量设置

#!/usr/bin/envpython

设置好后,不用显式的调用Python解释器,直接输入脚本名,脚本首行书写的启动指令会自动执行。

Eclipse,pycharm,idle等等,自己搜下.

表示最后一个表达式的值。所以上面的代码执行之后,下划线变量会包含字符串:

Python用下划线作为变量前缀和后缀指定特殊变量

_xxx保护变量不能用’frommoduleimport*’导入

__xxx__系统定义名字的专用方法

__xxx类中的私有变量名

程序员避免用下划线作为变量名的开始。

“单下划线”开头的成员变量叫做保护变量,是只有类对象和子类对象自己能访问到这些变量。这种变量不能直接访问,需通过类提供的接口进行访问,不能用“fromxxximport*”而导入。

只以“双下划线”开头的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。

以双下划线开头和结尾的如__foo__,是特殊方法标识,如__init__()代表类的构造函数。

可实现字符串替换功能,类似C语言:

>>>print"%sisnumber%d!"%("Python",1)

Pythonisnumber1!

符号>>用来重定向输出,将输出重定向到标准错误输出:

importsys

print>>sys.stderr,'Fatalerror:invalidinput!'

将输出重定向到日志文件的例子:

logfile=open('/tmp/mylog.txt','a')

print>>logfile,'Fatalerror:invalidinput!'

logfile.close()

内建函数help()得到一个生疏函数的帮助,用函数名得到相应的帮助信息

>>>help(raw_input)

Helponbuilt-infunctionraw_inputinmodule__builtin__:

raw_input(...)

raw_input([prompt])->string

注意,文档字符串的特别注释,是运行时访问,用来自动生成文档,如deffoo():

"Thisisadocstring."

returnTrue

函数名下一行,如果内容多,用三个单引号“’”,就可以跨行了

+-*///%**

两种除法运算符,单斜杠用作传统除法,双斜杠用作浮点除法(对结果进行四舍五入)

双星号(**)为乘方运算符,如3**2结果为9

<<=>>===!=<>

不许类型关键字,直接复制

>>>miles=1000.0

>>>name='Bob'

>>>counter=counter+1

支持增量赋值

n=n*10

n*=10

不支持自增1和自减1运算符,--n解释为-(-n)从而得到n,同样++n的结果也是n.

int(有符号整数)

long(长整数):长整数后缀“L”如2001L

bool(布尔值)

float(浮点值)

complex(复数)

Python的长整数所能表达的范围远远超过C语言的长整数,事实上,Python长整数仅受限于用户计算机的虚拟内存总数。如果你熟悉Java,Python的长整数类似于Java中的BigInteger类型。

True会被当成整数值1,而False则会被当成整数值0

复数(包括-1的平方根,即所谓的虚数)在其它语言中通常不被直接支持(一般通过类来实现)。

decimal用于十进制浮点数。不是内建类型,需要导入decimal模块,使用如字1.1无法用二进制浮点数精确表示

>>>1.1

1.1000000000000001

>>>printdecimal.Decimal('1.1')

1.1

可以看成是只读的列表。通过切片运算([]和[:])可以得到子集,这一点与字符串的使用方法一样。但切片得到的结果也是元组(不能被修改)

>>>aTuple=('robots',77,93,'try')

>>>aTuple

('robots',77,93,'try')

>>>aTuple[:3]

('robots',77,93)

>>>aTuple[1]=5

Traceback(innermostlast):

File"",line1,in

TypeError:objectdoesn'tsupportitemassignment

接受可迭代对象(例如序列或迭代器)作为其参数,每次迭代其中一个元素。如

foritemin['e-mail','net-surfing','homework','chat']:

printitem

Python提供了一个range()内建函数来生成这种列表,满足for的需要,接受一个数值范围,生成一个列表:

>>>foreachNuminrange(3):

printeachNum

也可以用len()配合foriinrange(len(foo))

同时循环两个,enumerate()同时循环索引和元素

fori,chinenumerate(foo):

printch,'(%d)'%i

在一行中使用一个for循环将所有值放到一个列表当中

>>>squared=[x**2forxinrange(4)]

>>>foriinsquared:

printi

输出结果:

0

1

4

9

更复杂如挑选出符合要求的值放入列表

sqdEvens=[x**2forxinrange(8)ifnotx%2]

foriinsqdEvens:

输出结果

16

36

注意,file()内建函数,功能等同于open(),这个名字可以更确切的表明它是一个工厂函数

可以是简单的数据值,也可以是可执行对象,如函数和方法。

使用“.”访问对象属性,如object.attribute。

代码

filename=raw_input('Enterfilename:')

fobj=open(filename,'r')

foreachLineinfobj:

printeachLine,

fobj.close()

其中,使用逗号来抑制自动生成的换行符号。文件中的每行文本已经自带了换行字符,如果我们不抑制print语句产生的换行符号,文本在显示时就会有额外的空行产生。

但对于很大的文件来说,上面的代码会占用太多的内存,这时你最好一次读一行。

遇到错误抛出的信息,迅速定位问题并进行调试

代码添加错误检测及异常处理,封装在try-except语句当中。except之后是处理错误的代码。可以用raise直接抛出一个异常。

try:

printeachLine,fobj.close()

exceptIOError,e:

print'fileopenerror:',e

class关键字定义,提供一个可选的父类或者说基类;如果没有合适的基类,

那就使用object作为基类。class行之后是可选的文档字符串,静态成员定义,及方法定

义。

classFooClass(object):

"""myveryfirstclass:FooClass"""

version=0.1#class(data)attribute

def__init__(self,nm='JohnDoe'):

"""constructor"""

self.name=nm#classinstance(data)attribute

print'Createdaclassinstancefor',nm

defshowname(self):

"""displayinstanceattributeandclassname"""

print'Yournameis',self.name

print'Mynameis',self.__class__.__name__

defshowver(self):

"""displayclass(static)attribute"""

printself.version#referencesFooClass.version

defaddMe2Me(self,x):#doesnotuse'self'

"""apply+operationtoargument"""

returnx+x

其中定义了一个静态变量version,它将被所有实例及四个方法共享,__init__(),showname(),showver(),及熟悉的addMe2Me().这些show*()方法并没有做什么有用的事情,仅仅输出对应的信息。

__init__()方法,名字开始和结束都有两个下划线的方法都是特殊方法。这个方法用于类实例初始化时首先调用,类似构建函数。不过不象其它语言中的构建函数,它并不创建实例--它仅仅是你的对象创建后执行的第一个方法。它的目的是执行一些该对象的必要的初始化工作。默认的__init__()方法什么都不做,可以覆盖重写。

每个方法都有的一个参数,self.是类实例自身的引用。类似其他语言使用的this

PEP就是一个Python增强提案(PythonEnhancementProposal),这也是在新版Python中增加新特性的方式。不但提供了新特性的完整描述,还有添加这些新特性的理由,如果需要的话,还会提供新的语法、技术实现细节、向后兼容信息等等。

20、实用的内建函数

dir([obj])显示对象的属性,如果没有提供参数,则显示全局变量的名字

type(obj)返回对象的类型(返回值本身是一个type对象!)

int()

str()

help()

代码跨行写用反斜线(\),继续上一行

而分号(;)将两个语句连接在一行中

使用四个空格宽度,避免使用制表符

赋值并不是直接将一个值赋给一个变量,尽管其它语言编程如此。但Python中,对象是通过引用传递的。在赋值时,不管这个对象是新创建的,还是一个已经存在的,都是将该对象的引用(并不是值)赋值给变量。

c语言中,赋值语句其实是被当成一个表达式(可以返回值),但python中不行,Python的赋值语句不会返回值,非法语句如

>>>x=1

>>>y=(x=x+1)#assignmentsnotexpressions!File"",line1

报错

y=(x=x+1)

^

SyntaxError:invalidsyntax

Python不支持类似x++或--x这样的前置/后置自增/自减运算

但支持增量赋值,运算符如下

+=-=*=/=%=**=

<<=>>=&=^=|=

多个变量同时赋值,如x,y,z=1,2,'astring'

交换两个变量值想x和y

x,y=1,2

x,y=y,x

关键字

专用下划线标识符

_xxx不用'frommoduleimport*'导入

__xxx__系统定义名字

避免用下划线作为变量名的开始,下划线对解释器有特殊的意义。

变量名_xxx被看作是“私有的”,在模块或类外不可以使用。当变量是私有的时候,用_xxx来表示变量是很好的习惯。因为变量名__xxx__对Python来说有特殊含义。

模块结构和布局,推荐的标准风格,如下

使用main()函数,检查__name__变量的值

如果模块是被导入,__name__的值为模块名字

如果模块是被直接执行,__name__的值为'__main__'

变量无须指定类型

程序员不用关心内存管理

变量名会被“回收”

del语句能够直接释放资源

(1)动态类型

Python语言中,对象的类型和内存占用都是运行时确定的。尽管代码被编译成字节码,Python仍然是一种解释型语言。在创建事,也就是赋值时,解释器会根据语法和右侧的操作数来决定新对象的类型。

(2)内存分配

Python解释器承担了内存管理的复杂任务,底层的事情放心交给Python解释器

Python创建对象,是作为引用来使用(赋值的),创建时在申请一个内存空间,同时为这个内存空间生成一个引用计数器,来记录该对象的引用传递给了多少对象(也是,多少新对象指向它)。所以,x=2,在python中先生成一个值为2的内存空间,并生成对应的引用计数器值为0,再将其的引用传给对象x,内存空间2的引用计数器加1(为1),x=y时,y同样指向内存空间2,其计数器继续加1(为0)。

书上说:Python内部记录着所有使用中的对象各有多少引用。一个内部跟踪变量,称为一个引用计数器。当对象被创建时,就创建了一个引用计数,当不再需要时,引用计数变为0时,它被垃圾回收。

引用计数器增加情况

(1)对象被创建

x=3.14

(2)或另外的别名被创建

y=x

(3)或被作为参数传递给函数(新的本地引用)

foobar(x)

(4)成为容器对象的一个元素

myList=[123,x,'xyz']

引用计数器减少情况

(1)一个本地引用离开了其作用范围。如传入函数的fun(x),x在fun()结束后销毁,对应减1

(2)对象的别名被显式的销毁。

dely#ordelx

(3)对象的一个别名被赋值给其它的对象

x=123

(4)对象被从一个窗口对象中移除

myList.remove(x)

(5)窗口对象本身被销毁

delmyList#orgoesout-of-scope

31、垃圾收集

不再被使用的内存会被一种称为垃圾收集的机制释放。虽然解释器跟踪对象的引用计数,但垃圾收集器负责释放内存。垃圾收集器是一块独立代码,用来寻找引用计数为0的对象。虽然引用计数大于0但也应该被销毁的对象。特定情形会导致循环引用。解释器会暂停下来,试图清理所有未引用的循环。

32、使用局部变量替换模块变量

os.linesep字符串给出当前平台使用的行终止符。为os.linesep属性取了一个新别名,这样做一方面可以缩短变量名,另一方面也能改善访问该变量的性能。

Importos

ls=os.linesep

#writelinestofilewithproperline-ending

fobj=open(fname,'w')

fobj.writelines(['%s%s'%(x,ls)forxinall])

类似os.linesep这样的名字需要解释器做两次查询,模块内部函数需要解释器做两次查询,因为模块也是全局变量。这样做多耗费资源。

一个函数中类似这样频繁使用一个属性,我们建议你为该属性取一个本地变量别名。在查找全局变量之前,总是先查找本地变量,经常用到的模块属性替换为一个本地引用。

33、一种新的Python结构,try-except-else语句

try子句是监测错误的代码块,

1#!/usr/bin/envPython

2#getfilename

3fname=raw_input('Enterfilename:')

4try:

5fobj=open(fname,'r')

6exceptIOError,e:

7print"***fileopenerror:",e

8else:

9#displaycontentstothescreen

10foreachLineinfobj:

11printeachLine,

12fobj.close()

34、必须工具

Python代码风格指南(PEP8),Python快速参考和Python常见问答。

优秀的Python程序员必用一些模块:

Debugger:pdb

Logger:logging

Profilers:profile,hotshot,cProfile

调试模块pdb允许你设置(条件)断点,代码逐行执行,检查堆栈。它还支持事后调试。

logging模块是在Python2.3中新增的,它定义了一些函数和类帮助你的程序实现灵活的日志系统。共有五级日志级别:紧急,错误,警告,信息和调试。

性能测试模块

(1)pyhonprofile模块(Python写成的,最老,最慢)

(2)hotshot模块(C语言写成,性能高)

python2.2中新增,目标是取代profile模块,修复profile模块的一些错误。

(3)hotshot模块

(4)cProfile模块(C语言)

身份:每个对象唯一的身份标识,使用内建函数id()来得到,可以认为是对象的内存地址。不用关心。

类型:内建函数type()查看对象类型,返回值为对象非字符串。类型决定值、操作、规则,如

type(type(42))

值:对象数据项

特殊类型NoneType:只有一个值None,没有任何运算,没有任何内建方法。布尔值总是False。

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

(2)帧:执行栈帧,命令执行时的记录对象,包含Python解释器在运行时所需要知道的所有信息

(3)跟踪记录:报异常时创建追踪对象,保存栈追踪信息。当异常有自己的处理程序,则去访问这个跟踪记录的对象,执行处理异常。

(4)切片对象:Python扩展的切片语法。sequence[start1:end1,start2:end2].也可以由内建函数slice()来生成.不同的索引切片操作,包括

步进切片:sequence[起始索引:结束索引:步进值],例子

>>>foolist=[123,'xba',342.23,'abc']

>>>foolist[::-1]

['abc',342.23,'xba',123]

多维切片:语法sequence[start1:end1,start2:end2],

省略切片:sequence[...,start1:end1]

(5)省略:用于扩展切片语法中,起记号作用。唯一的名字Ellipsis,布尔值始终为True.

(6)Xrange:返回一个对象

(1)对象值的比较:可以连着

3<4<7#sameas(3<4)and(4<7)

4<3<5!=2<7

不等于使用“!=”

对象间用is/isnot比较,如

b=2.5e-5

a=b

aisb

返回结果为TRUE

(2)特殊的对象:

简单整数对象被缓存,多次赋值只用这一个对象。

整数对象和字符串对象是不可变对象,所以Python会高效的缓存,造成我们认为Python应该创建新对象时,却没有创建新对象的假象。例子如下

>>>a=1

>>>id(a)

8402824

>>>b=1

>>>id(b)

>>>

>>>c=1.0

>>>id(c)

8651220

>>>d=1.0

>>>id(d)

8651204

其中,a和b指向了相同的整数对象(地址一样),但是c和d并没有指向相同的浮点数对象(地址不同)。也就是说,Python仅缓存简单整数(但这个功能不要使用),目前,简单整数的缓存范围是(-1,100),不过这个范围是会改变的,所以请不要在你的应用程序使用这个特性。

另外,预定义缓存字符串表之外的字符串,不再有任何引用指向它,那这个字符串将不会被缓存。对象回收器一样可以回收不再被使用的字符串

cmp(obj1,obj2)比较obj1和obj2,根据比较结果返回整数i:

i<0ifobj1

i>0ifobj1>obj2

i==0ifobj1==obj2

repr(obj)或`obj`返回一个对象的字符串表示

str(obj)返回对象适合可读性好的字符串表示

type(obj)得到一个对象的类型,并返回相应的type对象

注意repr()或反引号运算符“``”,以及str()三者完全一样,repr()输出对Python比较友好,而str()的输出对人比较友好。

repr()和``做的是完全一样的事情,返回一个对象的“官方”字符串表示,也就是说绝大多数情况下可以通过求值运算(使用eval()内建函数)重新得到该对象,但str()则有所不同。生成一个对象的可读性好的字符串表示,返回结果通常无法用于eval()求值,但用于print语句输出。

比type()好一点,功能一样。因为提升性能方法:

(1)减少函数调用次数(尽量使用变量做比较项目)

(2)减少查询次数,from-import,你可以减少一次查询:

fromtypesimportIntType

iftype(num)isIntType...

Python2.2统一了类型和类,所有内建类型也都是类。其内建转换函数如int(),type(),list()等等,都是类。看着像函数,实际是类。调用时也是生成实例。

“基本”,是指这些类型都是Python提供的标准或核心类型。

“内建”,是由于这些类型是Python默认就提供的

“数据”,因为他们用于一般数据存储

“对象”,因为对象是数据和功能的默认抽象

“原始”,因为这些类型提供的是最底层的粒度数据存储

“类型”,因为他们就是数据类型

标量/原子类型数值(所有的数值类型),字符串(全部是文字)

容器类型列表、元组、字典

可变类型列表,字典

不可变类型数字、字符串、元组

1,char或byte

如果要使用类似功能,可用长度为1的字符串,作为代替表示字符或8比特整数。

2,指针

内存地址python自动管理,不能手动管理,最多用id()函数得到对象身份号,类似但不是地址。Python中,一切都是指针。

3,整型不分int,short,long

Python的标准整型,融合了C中的长整型功能。而python的长整型(后边加L)是具有超级取值空间。如果两个很大的数相乘,Python会自动的返回一个长整数给你而不会报错。不像C。

4,Python决定不支持单精度浮点数

Python中只有一种浮点数类型。但是对需要更高精确度而宁愿放弃更大的取值范围情况,Python还有一种十进制浮点数类型Decimal,使用时需要decimal模块

Python标准整数类型等价于C中(有符号)长整型。八进制整数以数字“0”开始,十六进制整数则以“0x”或“0X”开始

整数值后面加个L(大写或小写都可以)。十进制,八进制,或十六进制都行。

C的长整型取值范围32位或64位。而python长整数不同,没有位数限制,能表达的值仅仅与机器的(虚拟)内存大小有关,范围很大,可以表达超级整数。

注意:

python中,整型计算多大会自动转换成长整型,所以

python不存在整数超范围的错误,只会给个warning,如

2<<32

给出信息:__main__:1:FutureWarning:x<

。每个浮点数占8个字节(64比特),完全遵守IEEE754号规范(52M/11E/1S),其中52个比特用于表示底,11个比特用于表示指数(可表示的范围大约是正负10的308.25次方),剩下的一个比特表示符号。但实际精度依赖于机器架构和创建Python解释器的编译器。

“+”对不用类型不同操作,不仅是加法

整数转换为浮点数,非复数转换为复数。Python提供了coerce()内建函数来帮助你实现这种转换。

1//2#floorsresult,returnsinteger#地板除,返回整数

>>>1.0//2.0#floorsresult,returnsfloat#地板除,返回浮点数

0.0

expr1//expr2表达式1地板除以表达式2

expr1%expr2表达式1对表达式2取

>>>-1//2#moveleftonnumberline#返回比–0.5小的整数,也就是-1

取反(~),按位与(&),或(|)及异或(^)及左移(<<)和右移(>>)只支持整数。

五个数值运算内建函数:

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=0)接受一个浮点数flt并对其四舍五入,保存ndig位小数。若不提供ndig参数,则默认小数点后0位。

round()仅用于浮点数。(译者注:整数也可以,不过并没有什么实际意义)

其中,coerce(),返回一个类型转换后的包含两个数值元素的元组。是不依赖Python解释器的数据类型转换函数,如

>>>coerce(1,2)

(1,2)

>>>coerce(1.3,134L)

(1.3,134.0)

>>>coerce(1j,134L)

(1j,(134+0j))

>>>coerce(1.23-41j,134L)

((1.23-41j),(134+0j))

divmod()内建函数把除法和取余运算结合起来,返回一个包含商和余数的元组

>>>divmod(10,3)

(3,1)

函数pow()是指数运算,功能和双星号(**)一样,但pow(x,y,z)有第三个可选的参数,叫余数参数。pow()先进行指数运算,然后将运算结果和第三个参数进行取余运算。这个特性主要用于密码运算,并且比pow(x,y)%z性能更好

(1)进制转换函数oct()和hex()

>>>hex(23094823l)

'0x1606627L'

>>>hex(65535*2)

'0x1fffe'

>>>oct(255)

'0377'

>>>oct(23094823l)

'0130063047L'

>>>oct(65535*2)

'0377776'

(2)ASCII转换函数ord()和chr()

ord('a')

97

>>>ord('A')

65

>>>chr(97)

'a'

>>>chr(65L)

'A'

另外,注意

chr(num)将ASCII值的数字转换成ASCII字符,范围只能是0<=num<=255

ord(chr)接受一个ASCII或Unicode字符(长度为1的字符串),返回相应的ASCII或Unicode值

unichr(num)接受Unicode码值,返回其对应的Unicode字符。所接受的码值范围依赖于Python是构建于UCS‐2还是UCS‐4

天生缺憾的表达,如

>>>0.1

0.1000000000000001

这些片断不停的重复直到舍入出错。所以针对数据类型,使用对应的类型

decimal十进制浮点运算类Decimal

array高效数值数组(字符,整数,浮点数等等)

math/cmath标准C库数学运算函数。常规数学运算在match模块,

复数运算在cmath模块

Operator数字运算符的函数实现。比如tor.sub(m,n)等价于m-n

random多种伪随机数生成器

这些片断不停的重复直到舍入出错

高级的数字科学计算应用的著名的第三方包Numeric(NumPy)和SciPy:

randint()两个整数参数,返回二者之间的随机整数

randrange()它接受和range()函数一样的参数,随机返回

range([start,]stop[,step])结果的一项

uniform()几乎和randint()一样,不过它返回的是二者之间的一个浮点数(不包括范围上限)。

random()类似uniform()只不过下限恒等于0.0,上限恒等于1.0

choice()随机返回给定序列(关于序列,见第六章)的一个元素

seq[ind]获得下标为ind的元素

seq[ind1:ind2]获得下标从ind1到ind2间的元素集合

seq*expr序列重复expr次

seq1+seq2连接序列seq1和seq2

objinseq判断obj元素是否包含在seq中

objnotinseq判断obj元素是否不包含在seq中

切片有很多小技巧,自己查,如

s[::-1]#可以视作"翻转"操作

s[::2]#隔一个取一个的操作

序列本身内含迭代的概念,是简单的迭代器。

(1)各类型之间的转换:转换实际上是工厂函数,将参数的内容(浅)拷贝到新生成对象

list(iter)把可迭代对象转换为列表

str(obj)把obj对象转换成字符串(对象的字符串表示法)

unicode(obj)把对象转换成Unicode字符串(使用默认编码)

basestring()抽象工厂函数,其作用仅仅是为str和unicode函数提供父类,所以不能被实例化,也不能被调用

tuple(iter)把一个可迭代对象转换成一个元组对象

其中,建立python后不能更改其身份或类型。建立一个浅拷贝,只拷贝了对象的索引,而不是重新建立了一个对象。

注意,len(),reversed()和sum()函数只能接受序列类型对象作为参数,而剩下的则还可以接受可迭代对象做为参数,另外,max()和min()函数也可以接受一个参数列表,如下

enumerate(iter)接受一个可迭代对象作为参数,返回一个enumerate对象(同时也是一个迭代器),该对象生成由iter每个元素的index值和item值组成的元组(PEP279)

len(seq)返回seq的长度

max(iter,key=None)ormax(arg0,arg1...,key=None)返回iter或(arg0,arg1,...)中的最大值,如果指定了key,这个key必须是一个可以传给sort()方法的,用于比较的回调函数

min(iter,key=None)ormin(arg0,arg1....key=None)返回iter里面的最小值;或者返回(arg0,arg2,...)里面的最小值;如果指定了key,这个key必须是一个可以传给sort()方法的,用于比较的回调函数.

reversed(seq)接受一个序列作为参数,返回一个以逆序访问的迭代器(PEP322)

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,...这些元素的第一个元素组成的一个元组,第二个...,类推.

特殊的序列:字符串的切片操作

成员操作符(in,notin)判断一个字符或者一个子串(中的字符)是否出现在另一个字符串中。出现则返回True,否则返回False

判断一个字符串是否包含另一个字符串的find()或者index(),还有rfind()和rindex())函数来完成

>>>'bc'in'abcd'True

>>>'n'in'abcd'False

>>>'nm'notin'abcd'True

string模块预定义的字符串:

>>importstring

>>>string.ascii_uppercase

'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

>>>string.ascii_lowercase

'abcdefghijklmnopqrstuvwxyz'

>>>string.ascii_letters

'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

>>>string.digits

'0123456789'

所以,可以简单的写一个检查小脚本,标识符检查idcheck.py

#Python标识符必须以字母或下划线开头,后面跟字母,下划线或者数字

importstring

alphas=string.letters+'_'

nums=string.digits

print'WelcometotheIdentifierCheckerv1.0'

print'Testeesmustbeatleast2charslong.'

inp=raw_input('Identifiertotest')

iflen(myInput)>1:

ifmyInput[0]notinalphas:

print'''invalid:firstsymbolmustbealphabetic'''

else:

forotherCharinmyInput[1:]:

ifotherCharnotinalphas+nums:

print'''invalid:remainingsymbolsmustbealphanumeric'''

break

print"okayasanidentifier"

性能的的角度,把重复操作作为参数放到循环里面进行是非常低效的,如

whilei

print'character%dis:',myString[i]

其中,len(myString)每次都被计算,浪费资源,改成

length=len(myString)

whilei

%c转换成字符(ASCII码值,或者长度为一的字符串)

%r优先用repr()函数进行字符串转换

%s优先用str()函数进行字符串转换

%d/%i转成有符号十进制数

%u转成无符号十进制数

%o转成无符号八进制数

%x/%X(Unsigned)转成无符号十六进制数(x/X代表转换后的十六进制字符的大小写)

%e/%E转成科学计数法(e/E控制输出e/E)

%f/%F转成浮点数(小数部分自然截断)

%g/%G%e和%f/%E和%F的简写

%%输出%

辅助的字符串格式化符号

*定义宽度或者小数点精度

-用做左对齐

+在正数前面显示加号(+)

在正数前面显示空格

#在八进制数前面显示零('0'),在十六进制前面显示'0x'或者'0X'(取决于用的是'x'还是'X')

0显示的数字前面填充‘0’而不是默认的空格

%'%%'输出一个单一的'%'

(var)映射变量(字典参数)

m.nm是显示的最小总宽度,n是小数点后的位数(如果可用的话)

举几个例子

>>>"%#X"%108

'0X6C'

>>>"%#x"%108

'0x6c'

>>>'%.2f'%1234.567890

'1234.57'

>>>'%E'%1234.567890

'1.234568E+03'

>>>'%e'%1234.567890

'1.234568e+03'

>>>'%g'%1234.567890

>>>'%G'%1234.567890

>>>"%e"%(1111111111111111111111L)

'1.111111e+21'

>>>"%+d"%4

'+4'

>>>"%+d"%-4

'-4'

新式的字符串模板

优势是不用记所有细节,而如shell风格那样使用美元符号($).由于新式的字符串Template对象的引进使得string模块又重新活了过来,Template对象有两个方法,substitute()和safe_substitute(),如

>>>fromstringimportTemplate

>>>s=Template('Thereare${howmany}${lang}QuotationSymbols')

>>>prints.substitute(lang='Python',howmany=3)

结果Thereare3PythonQuotationSymbols

>>>s,t='foa','obr'

>>>zip(s,t)

[('f','o'),('o','b'),('a','r')]

str()和unicode()函数都是工厂函数,就是说产生所对应的类型的对象,它们和basestring都可以作为参数传给isinstance()函数来判断一个对象的类型

>>>isinstance(u'\0xAB',str)

False

>>>notisinstance('foo',unicode)

True

>>>isinstance(u'',basestring)

>>>notisinstance('foo',basestring)

字符串前加u表示编码成Unicode字符串,如,如u’sdfad’是Unicode字符串。

Unicode是编码方式,用于计算机支持都语言的。ASCII编码方式中每个英文字符以七位二进制数的方式存贮在计算机内,其范围是32到126,目前8为可以表示128种。

codec是COder/DECoder的首字母组合,定义了文本跟二进制值的转换方式。ASCII用一个字节把字符转换成数字。而nicode用的是多字节,支持多种编码,常用的四种ASCII,ISO8859-1/Latin-1,UTF-8和UTF-16。

UTF-8编码跟ASCII编码完全相同。用1个到4个字节来表示其他语言的字符,CJK/East这样的东亚文字一般都是用3个字节来表示,那些少用的、特殊的、或者历史遗留的字符用4个字节来表示。Python内部自动完成UTF-8读写工作,不需要关心,免去了直接处理Unicode数据时处理多字节字符的复杂问题。

代码如下:

CODEC='utf-8'

hello_out=u"Helloworld\n"

bytes_out=hello_out.encode(CODEC)

hello_in=bytes_in.decode(CODEC)

printbytes_out,hello_in

UTF-16用16位、两个字节来存储字符,易读写。但顺序需要定义一下,一般UTF-16编码文件都需要一个BOM(ByteOrderMark),或者你显式地定义UTF-16-LE(小端)或者UTF-16-BE(大端)字节序。UTF-16是一种变长编码,不常用,因为不兼容包ASCII,而且一般不会知道或者根本不在意除了基本多文种平面BMP之外到底使用的是那种平面,

Python标准库里面的绝大部分模块都是兼容Unicode的。但pickle模块只支持ASCII字符串。如果你把一个Unicode字符串交给pickle模块来unpickle,它会报异常.你必须先把你的字符串转换成ASCII字符串才可以.所以最好是避免基于文本的pickle操作.幸运地是现在二进制格式已经作为pickle的默认格式了,pickle的二进制格式支持不错.这点在你向数据库里面存东西是尤为突出,把它们作为BLOB字段存储而不是作为TEXT或者VARCHAR字段存储要好很多.万一有人把你的字段改成了Unicode类型,这可以避免pickle的崩溃.

另外,使用第三方模块时要注意Unicode通讯方面遇到麻烦,要设置好环境中相应的参数设置

正则表达式引擎需要Unicode支持.详见6.9节的re模块

常用Unicode编辑码

编码描述

utf-8变量长度为8的编码(默认编码)

utf-16变量长度为16的编码(大/小端)

utf-16-le小端UTF-16编码

utf-16-be大端UTF-16编码

ascii7-bit7位ASCII码表

iso-8859-1ISO8859-1(Latin-1)码表

unicode-escape(定义见PythonUnicode构造函数)

raw-unicode-escape(定义见PythonUnicode构造函数)

nativePython用的内部格式

模块描述

re正则表达式:强大的字符串模式

struct字符串和二进制之间的转换

c/StringIO字符串缓冲对象,操作方法类

base64Base16,32,64数据编解码

codecs解码器注册和基类

crypt进行单方面加密

diffliba找出序列间的不同

hashlib多种不同安全哈希算法和信息摘要

hmaHMAC信息鉴权算法的Python

md5RSA的MD5信息摘要鉴权

rotor提供多平台的加解密服务

shaNIAT的安全哈希算法SHA

stringprep提供用于IP协议的Unicode字符串

textwrape文本打包和填充

unicodedataUnicode数据库

不需要像C一样添加结束符,python自动管理,字符串中只包含你所定义的东西,没有别的。

Python中没有特定用于列表的内建函数。只有range()函数接受一个数值作为输入,输出一个符合标准的列表.

列表类型支持的所有方法:

list.append(obj)向列表中添加一个对象obj

list.count(obj)返回一个对象obj在列表中出现的次数

list.extend(seq)把序列seq的内容添加到列表中

list.index(obj,i=0,j=len(list))返回list[k]==obj的k值,并且k的范围在i<=k

引发ValueError异常.

list.insert(index,obj)在索引量为index的位置插入对象obj.

list.pop(index=-1)删除并返回指定位置的对象,默认是最后一个对象

list.remove(obj)从列表中删除对象obj

list.reverse()原地翻转列表

list.sort(func=None,key=None,reverse=False)以指定的方式排序列表中的成员,如果func和key参数指定,则按照指定的方式比较各个元素,如果reverse标志被置为True,则列表以反序排列.

python方法不一定有返回值,如sort(),extend()和reverse()这些操作在列表中原地执行操作,原列表内容被改变,没有返回值。与之相反,字符串不能被改变,所以这些函数产生新对象,一定会有返回值。

元组也没有它自己专用的运算符和内建函数,因为元组是不可变的,没有实现排序,替换,添加等方法

但元组也可以间接的变化,如两个元组用加号+连接;或者元组元素为列表,就可以增减元素。

注意,有符号封装的多对象集合其实是返回的一个单一的容器对象,如

deffoo1():

:

returnobj1,obj2,obj3#等同于return(obj1,obj2,obj3)

'xyz'

>>>type(('xyz'))#astring,notatuple

数组一种受限制的可变序列类型,要求所有的元素必须都是相同的类型

copy提供浅拷贝和深拷贝的能力

operator包含函数调用形式的序列操作符,比如operator.concat(m,n)就相当于连接操作(m+n)。

rePerl风格的正则表达式查找(和匹配);见第15章

StringIO/cStringIO把长字符串作为文件来操作,比如read(),seek()函数等,C版的更快一些,但是它不能被继承.

Textwrap用作包裹/填充文本的函数,也有一个类

types包含Python支持的所有类型

collections高性能容器数据类型

copy模块中只有两个函数可用:

(1)copy()进行浅拷贝操作

(2)deepcopy()进行深拷贝操作

浅拷贝:没有申请新内存,新指针(地址)与原指针都指向一个内存,原来对象的内存。

也就是说,新创建了一个类型跟原对象一样,其内容是原来对象元素的引用,换句话说,这个拷贝的对象本身是新的,但是它的内容不是.

序列类型对象默认拷贝是浅拷贝,主要有以下几种方式实施:

(1)完全切片操作[:],

(2)利用工厂函数,比如list(),dict()等

(3)使用copy模块的copy函数

深拷贝:又叫完全拷贝。新申请内存,新指针(地址)指向新内存,新对象完全独立于老对象。

第一,非容器类型没有被拷贝一说,如数字,字符串和其他"原子"类型的对象,像代码,类型和xrange对象等,而浅拷贝是用完全切片操作来完成的

第二,如果元组变量只包含原子类型对象,那么深拷贝也相当于浅拷贝.因为内部是非容器类对象,python缓存了对象,所以只有一个内存空间。

如,我们把账户信息改成元组类型,那么即便按我们的要求使用深拷贝操作也只能得到一个浅拷贝:

>>>person=['name',('savings',100.00)]

>>>newPerson=copy.deepcopy(person)

>>>[id(x)forxinperson,newPerson]

[12225352,12226112]

>>>[id(x)forxinperson]

[9919616,11800088]

>>>[id(x)forxinnewPerson]

总之,

a.只有容器类才有拷贝概念,分深拷贝和浅拷贝;

b.非容器类不分,都是python缓存对象共享一个地址如字符串、数字;

c.复合容器(如list元素是元组,而元组的元素是list)的copy,其外部和内部对象分别对应自身对象的copy机制,外部list自身可以是深拷贝,但内部元组元素共享缓存独享(类似浅拷贝)、而外部元组类似浅拷贝时,内部list对象元素是深拷贝,代码如下:

importcopy

tuple1=([1,2,3],'a','b')

tuple3=tuple1#浅拷贝

tuple4=copy.deepcopy(tuple1)#深拷贝

print[id(x)forxintuple1]

print[id(x)forxintuple3]

print[id(x)forxintuple4]

输出结果为:

[40129800L,38969632L,39037848L]

[40558664L,38969632L,39037848L]

23、string、tuple、list的built-in函数

三者都支持的共享函数:

cmp()

len()

list()

max()

min()

[:]slice切片符号

*

+

In

notin

只有string和list共同支持的函数:

count()

index()

.attributes属性提取符号

另外,insert()、append()、extend()三者只有list支持。三者都是添加操作,前两个是添加单个元素,extend()是添加另一个list对象,相当于“+”操作符功能。

剩下的其他内建函数只有string支持,如zfill()、upper()、%、ord()、oct()、hex()、find()、expandtabs()、cpitalize()、center()、chr()、decode()、encode()、endswith()等等。

dict1={}

dict2={'name':'earth','port':80}

dict3=dict((['x',1],['y',2]))

注意用dict方法建立字典对象,可用于对象间的转化,转化list对象,然后转化为字典。

内建方法fromkeys()创建元素具有相同的值的字典(未给出,默认为None):

>>>ddict={}.fromkeys(('x','y'),-1)

>>>ddict

{'y':-1,'x':-1}

>>>edict={}.fromkeys(('foo','bar'))

>>>edict

{'foo':None,'bar':None}

forkeyindict2.keys():

...print'key=%s,value=%s'%(key,dict2[key])

或者简化直接用字典名

forkeyindict2:

3、判断元素村子尽量使用in和notin,不用has_key()

'name'indict2

4、删除字典元素和字典

deldict2['name']#删除键为“name”的条目

dict2.clear()#删除dict2中所有的条目

deldict2#删除整个dict2字典

dict2.pop('name')#删除并返回键为“name”的条目

5、请不要用内建类型为变量命名,如dict,list,file,bool,str,input,len

6、字典比较

先长度,然后逐个元素,先比较key,在比较value,谁大立刻返回1、0、-1

7、hash()

返回参数对象的哈希值。不是为字典设计的方法,可以判断某个对象是否可以做一个字典的键。

Set内部元素无序,所以不可以为集合创建索引或执行切片(slice)操作,也没有键(keys)可用来获取集合中元素的值。

可变集合(set):可添加删除元素

不可变集合(frozenset):不可以添加删除元素

工厂方法set()和frozenset():

参数必须是可迭代的,即,一个序列,或迭代器,或支持迭代的一个对象,例如:一个文件或一个字典

>>>s=set('cheeseshop')

>>>s

set(['c','e','h','o','p','s'])

>>>t=frozenset('bookshop')

>>>t

frozenset(['b','h','k','o','p','s'])

>>>type(s)

>>>type(t)

作用函数len()、==、in、notin:

例如:foriins:

...printi

添加、删除元素:

>>s.add('z')

set(['c','e','h','o','p','s','z'])

>>>s.update('pypi')

set(['c','e','i','h','o','p','s','y','z'])

>>>s.remove('z')

set(['c','e','i','h','o','p','s','y'])

>>>s-=set('pypi')

set(['c','e','h','o','s'])

不可变集合不能添加、删除元素,会报错

t.add('z')

Traceback(mostrecentcalllast):

AttributeError:'frozenset'objecthasnoattribute'add'

删除:dels

是判断两集合是超集或子集。只跟集合中元素组成有关,与元素顺序、集合长度等其他无关

“小于”符号(<,<=)用来判断子集;

“大于”符号(>,>=)用来判断超集。

>>>set('shop')

>>>set('bookshop')>=set('shop')

在while和for循环中使用else语句,else子句在循环完成后,最后执行,如果有break语句则会跳过else块。

迭代器一组数据结构,利用引从0开始一直"迭代"到序列的最后一个条目。支持多种对象,如字典,类对象。提升性能。

迭代通过对象的next()方法,而不是通过索引来计数,迭代全部完成后发出StopIteration异常作为结束标志,不是报错。代码如下

fetch=iter(seq)

whileTrue:

i=fetch.next()

exceptStopIteration:

do_something_to(i)

文件迭代

用reachLineinmyFile或者foreachLineinmyFile.readlines()都可以。如

myFile=open('config-win.txt')

foreachLineinmyFile:

...printeachLine,#commasuppressesextra\n

Listcomprehensions,或缩略为listcomps,简单实用的工具,用来动态地创建列表。

语法:exprforiter_variniterable

其中,expr是一个表达式,完成计算。

列表解析的表达式可以取代内建函数,而且效率更高。如map()、lambda、filter()等,被简化为一个列表解析式,函数功能:

map()对所有的列表成员应用一个操作

filter()基于一个条件表达式过滤列表成员

lambda允许你快速地创建只有一行的函数对象

例子:

map(lambdax:x**2,range(6))

可以简化为:[x**2forxinrange(6)]

扩展语法:

[exprforiter_variniterableifcond_expr]

例子,判断奇数:

>>>seq=[11,10,9,9,10,10,9,8,23,9,7,18,12,11,12]

>>>filter(lambdax:x%2,seq)

[11,9,9,9,23,9,7,11]

用列表解析:

>>>[xforxinseqifx%2]

三行五列的矩阵

>>>[(x+1,y+1)forxinrange(3)foryinrange(5)]

[(1,1),(1,2),(1,3),(1,4),(1,5),(2,1),(2,2),(2,3),(2,4),(2,5),(3,1),(3,2),(3,3),(3,4),(3,5)]

计算出所有非空白字符的数目,把每行分割(split)为单词

>>>f=open('hhga.txt','r')

>>>len([wordforlineinfforwordinline.split()])

计算文件大小

importos

>>>os.stat('hhga.txt').st_size

499L

列表解析统计非空字符(去空格)为

>>>f.seek(0)

>>>sum([len(word)forlineinfforwordinline.split()])

408

处理大文件时readlines()会读取文件的所有行,用迭代器,生成器表达式替换列表解析,比如用max()内建函数得到最长的字符串长度:

f=open('/etc/motd','r')

allLineLens=[len(x.strip())forxinf]

f.close()

returnmax(allLineLens)

用生成器表达式简化,移到max()中

longest=max(len(x.strip())forxinf)

returnlongest

文件只是连续的字节序列.数据的传输经常会用到字节流,无论字节流是由单个字节还是大块数据组成.

open()和file()一样,可相互替换。

出错产生IOError异常

建议使用open()读写文件,在在处理文件对象时使用file(),例如ifinstance(f,file).

write()或writelines()不会自动加入行结束符。因为read的时候不删除,所以自带。如没有必须自己加上。

seek()方法,参数offset

默认值为0代表文件开头

1代表从当前位置算起,

2代表从文件末尾算起

text()返回前文件指针在文件中的位置。从文件起始算起,单位为字节。

目前,使用文件迭代是最高效的方法,直接

foreachLineinf:

而老的方法file.xreadlines()最高效。

最差file.readlines()会一次读入所有行到一个列表,需要大内存。内存不足时,用readline()一次读入一行,但效率非常慢。遇到foreachLineinf.readline(),全部修改成文件迭代方式。

file.fileno()返回文件的描述符(filedescriptor,FD,整数

file.flush()刷新文件的内部缓冲区

file.isatty()判断file是否是一个类tty设备

file.next()返回文件的下一行(类似于file.readline()),或在没有其它行时引发StopIteration异常

file.seek(off,whence=0)在文件中移动文件指针,从whence(0代表文件其始,1代

表当前位置,2代表文件末尾)偏移off字节

file.tell()返回当前在文件中的位置

file.truncate(size=file.tell())截取文件到最大size字节,默认为当前文件位置

file.closedTrue表示文件已经被关闭,否则为False

file.encoding文件所使用的编码-当Unicode字符串被写入数据时,它们将自动使用file.encoding转换为字节字符串;若file.encoding为None时使

用系统默认编码

file.mode文件打开时使用的访问模式

file.name文件名

file.newlinesa未读取到行分隔符时为None,只有一种行分隔符时为一个字符串,当文件有多种类型的行结束符时,则为一个包含所有当前所遇到的行结束符的列表

file.softspace为0表示在输出一数据后,要加上一个空格符,1表示不加。这个属性

程序一执行,那么你就可以访问三个标准文件。分别是标准输入(一般是键盘),标准输出(到显示器的缓冲输出)和标准错误(到屏幕的非缓冲输出),对应为stdin,stdout和stderr。

(将多个函数的相同功能代码提取成一个装饰函数,用@+函数名放在函数前直接调用,实际是将被装饰函数作为参数传入装饰函数中,返回新的参数对象,原有被装饰函数对象作废)

类似于Java的AOP(AspectOrientedProgramming,面向方面编程)

一个用来包装函数的函数,返回一个修改之后的函数对象,将其重新赋值原来的标识符,并永久丧失对原始函数对象的访问。

用途:

引入日志、

增加计时逻辑来检测性能、

给函数增加事务的能力。

简单说,为已经存在的对象添加额外的功能。在函数执行前和执行后分别附加额外功能。

也就是,装饰函数的参数是被装饰的函数对象,返回原函数对象,实际上为myfunc=deco(myfunc),比如下面代码

1.defdeco(func):

2.printfunc

3.returnfunc

4.@deco

5.deffoo():pass

6.foo()

实际代码是foo=deco(foo)

普通装饰器,就是定义一个装饰函数名,以作用函数(需要包装的函数)为参数,内部定义封闭函数,也就是返回定义函数对,代码如下,看最后一行,返回内部封闭函数对象:

defdecorator(F):

defnew_F(a,b):

print("input",a,b)

returnF(a,b)

returnnew_F

如果装饰函数需要参数,而被装饰函数也有参数,就做三层包装:

#anewwrapperlayerdefpre_str(pre=''):#olddecoratordefdecorator(F):defnew_F(a,b):print(pre+"input",a,b)returnF(a,b)returnnew_Freturndecorator#getsquaresum@pre_str('^_^')defsquare_sum(a,b):returna**2+b**2

参数'^_^'是装饰函数的参数,F是被装饰函数名,而内部是包装的执行函数。也就是说有参数传入加一层。

在函数内部定义一个内部函数(嵌套函数),其引用了外部作用域的变量,并且不是全局变量,那么这个内部函数叫闭包。装饰器就是闭包。

函数调用自身叫递归,典型例子,阶乘factorial(N)=N*factorial(N-1),求N项值需要知道N-1项值。

生成器是带yield语句的函数:

(其实生成器对象就是有next()函数,每次调用直接返回yield后面的对象,也就是说yield是next()函数的返回标志,简单用途如每次返回列表第一个位置的元素)

能暂停执行并返回一个中间的结果(yield语句部分的功能:返回一个值给调用者并暂停执行),当调用next()方法时,会准确地从离开地方继续执行(当它将返回值和控制传递给调用者时)。而普通函数或者子程序只返回一次。

从_future_模块中导入generators来用生成器,从2.3开始直接用。

简单的生成器:

defsimpleGen():

yield1

yield'2-->punch!'

调用方法和执行结果:

myG=simpleGen()

myG.next()

输出:1

输出:'2-->punch!'

输出:Traceback(mostrecentcalllast):

File"",line1,inmyG.next()StopIteration

遇到next()没有值可返回,就抛出异常StopIteration。

(1)在交互式解释器会话中,“_”代表上一条执行的语句的结果。

(2)“_”作为临时性的名称使用,就是不会在后面再次用到该名称,而临时分配了一个特定的名称。如

n=42

for_inrange(n):

do_something()

(3)“_”作为一个函数来使用,如Django文档“转换”章节中的代码。这样用法易冲突,尽量不用。

(4)在程序代码中用法三种:

_xxx不能用'frommoduleimport*'导入

__xxx__系统定义名字(程序员自己不要这样命名)

__xxx类中的私有变量名(自动进行私有转换Privatenamemangling)

核心风格:避免用下划线作为变量名的开头。其他下划线用法都是为了避免命名重复。具体解释如下:

名称前的单下划线,类似一种惯例,指定该属性为“私有”,只供内部使用。

名称前的双下划线(如:__shahriar)为了避免与子类定义的名称冲突,私有变量名字改编(Privatenamemangling),即在代码生成之前被转换为长格式(变为公有),也就是变量前端加上下划线字符和类名“_类名”。代码实例如,有类A,

>>>classA(object):

...def_internal_use(self):

...pass

...def__method_name(self):

...

>>>dir(A())

['_A__method_name',...,'_internal_use']

在设计继承类B:

>>>classB(A):

>>>dir(B())

['_A__method_name','_B__method_name',...,'_internal_use']

a.py导入了模块b.py,而修改b.py的过程中添加导入模块a.py,就会报错,这是循环导入错误。

Import都是在a.py和b.py的文件开头。

解决办法有两个:

1,移除一个导入语句

2,将b.py的import语句放入函数内部。不要放在开头。

封装:数据属性对外隐藏,自身设计访问方法供外部使用

合成:将多个类合成一个类

泛化:提取共性做成父类

特化:设计新功能的子类

多态:调用不同对象的相同名称的函数,却具有不同的功能。

自省或反射:给出自身信息的功能,如提供结构,参数,对应函数等信息。

类方法是类内部定义的的函数,不是实例属性,是类属性;

存在实例后,方法才能绑定到类实例上,调用时通过类实例调用;

类中,任何方法定义中第一个参数都是变量self。

绑定方法的不同在于与实例绑定,所以调用绑定方法通过实例,不需要给出self参数。

而非绑定方法直接通过类调用(类名加点),且没有实例必须传递self参数。主要场景

派生一个子类要覆盖父类的方法,如构造方法

classEmplAddrBookEntry(AddrBookEntry):

def__init__(self,nm,ph,em):

AddrBookEntry.__init__(self,nm,ph)

self.empid=id

self.email=em其中,EmplAddrBookEntry是AddrBookEntry的子类,其重载了构造器__init__(),其中调用父类的构造器时没有父实例,明确的给出self参数。

Python类定义中,方法的第一参数是self,用于传递对象本身,调用时不显示传递。

而在子类中调用父类时,最简单的方法是把对象调用转换成类调用,此时,self参数必须显示传递。也就是说,子类定义时,使用super()调用父类时必须显示传递self参数,如

classFooParent:

defbar(self,message):

print(message)

classFooChild(FooParent):

super(FooChild,self).bar(message)#也可是FooParent.bar(self,message)

调用代码:FooChild().bar("Hello,World.")

其中,子类定义中使用super函数

第一参数是当前子类,

第二参数self

多重继承在super机制里可保证公共父类仅被执行一次,至于执行的顺序按照mro进行的,myclass.__mro__的属性

注意super继承只能用于新式类,用于经典类时就会报错。

新式类:必须有继承的类,如果没什么想继承的,那就继承object

经典类:没有父类,如果此时调用super就会出现错误:『super()argument1mustbetype,notclassobj』

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)给定键如果不存在字典中,则提供一个默认值

C.__*add__(self,obj)串连;+操作符

C.__*mul__(self,obj)重复;*操作符

其中,星号通配符标注的数值二进制操作符则表示这些方法有多个版本,在名字上有些许不同。

"*"代表''(selpOPobj),'r'(objOPself),或'i'(原位(in-place)操作,Py2.0新增),

例如__add__,__radd__,or__iadd__.

“*”eithernothing(selfOPobj),“r”(objOPself),or“i”forin-place

operation(newinPython1.6),i.e.,__add__,__radd__,or__iadd__.

实现这些特殊方法将会重载操作符,使它们可以处理你的类类型的实例。比如实例之间的+加号功能通过__add__()实现,而累加通过__iadd__(),右结合加号通过__radd__()实现。

从集合的第一个元素开始访问,直到所有的元素都被访问一遍后结束。

不能回退或者随机访问,只能往前进行迭代

不是线程安全的,在多线程环境中对可变集合使用迭代器是一个危险的操作,使用时小心。

优点:

是不要求事先准备好整个迭代过程中所有的元素。仅仅在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。这个特点被称为延迟计算或惰性求值(Lazyevaluation)。

统一的访问集合的接口。只要是实现了__iter__()方法的对象,就可以使用迭代器进行访问。

Python专门将关键字for用作了迭代器的语法糖。在for循环中,Python将自动调用工厂函数iter()获得迭代器,自动调用next()获取元素

自己设计迭代器:

迭代器有两个基本方法:

1)next方法:返回容器的下一个元素2)__iter__方法:返回迭代器自身

在类的__iter__方法中返回一个对象,这个对象拥有一个next()方法,这个方法能在恰当的时候抛出StopIteration异常即可。但是需要自己实现迭代器的时候不多,即使需要,使用生成器会更轻松

包装,是将一段代码重新功能封装,去除不要的,加新的,保留原有的。

派生是对类的包装。

classWrapMe(object):

def__init__(self,obj):

self.__data=obj

defget(self):

returnself.__data

def__repr__(self):

return‘self.__data‘

def__str__(self):

returnstr(self.__data)

def__getattr__(self,attr):

returngetattr(self.__data,attr)

例子中,可以看到将原始对象包装好后,给出__getattr__,比如

THE END
1.如何高效背单词背得住记得牢背单词学习方法英语学习快速记忆单词,让学习更轻松|史上最强单词记忆法|英语单词记忆诀窍|趣味学英语|单词怎么记得牢背的快|一周轻松记忆4000+单词 记忆力小课堂 4.4万 199 02:59 99%的高中生都错了|如何正确高效背单词 高中英语May老师 3979 3 00:42 告诉大家一个简单高效的背单词方法:7天滚动记忆法 王渊源John 22.5万 https://www.bilibili.com/list/ml1764757021
2.library怎么快速记忆?图形联系记忆。上网下些简单笔画的图片,书上应该也有吧。能让小孩子看到单词联想起画面。有词根的,比如https://www.3d66.com/answers/question_241760.html
3.图书馆英语怎么读?图书馆的英语单词是什么去图书馆读书用英语怎么说 图书馆的英语单词是什么 图书馆英语快速记法 图书馆的英语单词快速记忆法 一、图书馆复数 1、图书馆的英文是library,library的复数是libraries。 2、libraries的例句:Therearemanytheatres,museums,andlibrariesinParis(巴黎有许多剧院、博物馆和图书馆)。 http://www.yaolan.com/edu/taijiao/196928.html
4.超实用单词记忆法字根详细讲解系列3和看相关的字根和词汇超实用单词记忆法 字根详细讲解系列3 和看 相关的字根和词汇美言学社 广东 5 打开网易新闻 体验效果更佳听说这部电视很适合学英语 书本影视 276跟贴 打开APP 英国学生做亚洲的英语试卷,没想到做到一半直接懵了 阿Q大视野 497跟贴 打开APP 英专生开辟“新战场”,做“直播卖货”?英语也能这么玩!网友:直播感太https://m.163.com/v/video/VFILS87FB.html
5.如何有效记忆英语单词利用音标记忆法 音标记忆法记忆单词是最能持久记住单词的一种方法,也是最有效记忆单词的方法。作为一名中学英语教师,在初一的时候,就要提倡利用音标记忆法。因为刚刚学了音标,利用音标和单词结合起来学习和记忆,既使音标在单词得以应用,又能把音标记得更加牢,而且还为以后拼读单词打下良好的基础。这种一举三得的举措,何https://www.360wenmi.com/f/filep29vjuu7.html
6.快速记忆英语单词的五大方法快速记忆英语单词的五大方法 英语单词的产生是汉英两种语言双向交流的产物,一些带有中国特色的名称和概念进入了英语词汇,同时还有一些英语词汇进入了汉语,在文化环境中衍生出新的含义,形成了英语词汇的语义文化特征。英语词汇量很大,背单词如果做不到持之以恒,往往会作用不大,而且常常是即兴记忆。今天小编为大家精心准备https://www.cnfla.com/yingyu/561301.html
7.如何提高记忆力初三英语作文(共27篇)记忆的方法多种多样,各有长处和短处。我们要注意多种方法穿插使用,才能取得较好的结果。 篇4:英语高考怎么快速提高成绩与记忆力 如何快速提高高三英语成绩 多做高考真题积累经验 高考考察要点比较全面且难度适中。同学们可以把近三年的高考题从头到尾做一下,熟悉高考的思路。由于模拟题有的偏难,同学们可咨询老师,该https://www.hrrsj.com/zuowen/chusan/740513.html
8.关于不定积分的部分公式的快速记忆,目的在于,在研究生考试或者关于不定积分的部分公式的快速记忆,目的在于,在研究生考试或者需要手工计算不定积分时可以快速出答案。,程序员大本营,技术文章内容聚合第一站。https://www.pianshen.com/article/7536949696/
9.高考英语3500单词快速记忆法(联想记忆)学案学案下载高考英语3500单词快速记忆法(联想记忆)学案 展开 这是一份高考英语3500单词快速记忆法(联想记忆)学案,共91页。学案主要包含了词中词或复合词,谐音,组块或换字记忆等内容,欢迎下载使用。 ? 高考英语3500单词快速记忆法(联想记忆) adventure ;n.& vt.冒险;词中词 :venture 冒险;投机 risk; danger; adventurohttps://www.51jiaoxi.com/doc-12834447.html
10.字母编码记忆法帮你快速记单词以单词"english"为例,通过字母编码记忆法进行记忆: E:Earth(地球),将E与地球进行联系,表示英语的全球性。 N:Notebook(笔记本),将N与笔记本进行联系,表示学习英语需要记录笔记。 G:Globe(地球仪),将G与地球仪进行联系,表示英语是一种国际语言。 L:Library(图书馆),将L与图书馆进行联系,表示学习英语需要阅读。https://www.hjenglish.com/new/p1427902/
11.dictionary什么意思怎么读?单词用法记忆法发音音标反义词用户提交的单词: dictionary的快速记忆法 支持(82) 反对(0) 发布人:网友提供 发布时间:发布时间:2012-02-02 10:19:41 上一篇:film什么意思、怎么读?单词用法、记忆法、发音音标、反义词同义词辨析、例句造句、释义 栏目:六年级上册 Unit3 下一篇:space什么意思、怎么读?单词用法、记忆法、发音音标、反义词同义词https://english.downyuan.com/index.php?m=home&c=View&a=index&aid=l5550
12.library单词怎么记忆?台湾VPS活动时间2023年9月9日 9301130活动地点珠海市图书馆二楼演示厅;The library is anchored by a giant spherical structure in the center of 思维导图究竟怎么记单词?高中英语单词记忆方法附视频高;当然啦,分类记忆法也是个不错的主意想象一下,你的大脑就像是一个井井有条的图书馆,每个单词都有自己的专属书架你https://www.zovps.com/article/index.php/post/210907.html
13.最新高考英语3500单词快速记忆法(联想记忆).doc最新高考英语3500单词快速记忆法(联想记忆).doc 116页内容提供方:平凡 大小:421 KB 字数:约14.43万字 发布时间:2018-09-26发布于四川 浏览人气:766 下载次数:仅上传者可见 收藏次数:2 需要金币:*** 金币 (10金币=人民币1元)最新高考英语3500单词快速记忆法(联想记忆).doc 关闭预览 想预览更多https://max.book118.com/html/2018/0925/5034304332001314.shtm
14.如何快速大量记忆单词?英语词根记忆法Ⅸ(词根log)英语口语吧如何快速大量记忆单词..当词根log表示“说话”时1. logic [log(=to speak)+ic表示“学”]n. 逻辑(学);思维方式例句:I don't follow the logic of youhttps://tieba.baidu.com/p/6348732392