Python笔记.docx
《Python笔记.docx》由会员分享,可在线阅读,更多相关《Python笔记.docx(112页珍藏版)》请在冰豆网上搜索。
Python笔记
>>>foo='abc'
>>>foriinrange(len(foo)):
print(foo[i],'(%d)'%i)
a(0)
b
(1)
c
(2)
>>>fori,chinenumerate(foo):
print(ch,'(%d)'%i)
a(0)
b
(1)
c
(2)
列表解析
>>>squared=[x**2forxinrange(4)]
>>>foriinsquared:
print(i)
0
1
4
9
>>>sqdEvens=[x**2forxinrange(8)ifnotx%2]
>>>foriinsqdEvens:
print(i)
0
4
16
36
文件读取
filename=input('Enterfilename:
')
fobj=open(filename,'r')
foreachLineinfobj:
print(eachLine)
fobj.close()
这段代码一次读入文件的所有行,然后关闭文件,再迭代每一行输出,不过这段代码适合文件大小适中的文件,因为对于很大的文件,上面的代码会占用太多的内存,这时你最好一次读一行。
定义函数
defaddMe2Me(x):
'apply+operationtoargument'
return(x+x)
默认参数:
函数的参数可以有一个默认值
deffoo(debug=True):
'determineifindebugmodewithdefaultargument'
ifdebug:
print('indebugmode')
print('done')
如何定义类
classFooClass(object):
version=0.1
def__init__(self,nm='JohnDoe'):
self.name=nm
print('Createdaclassinstancefor',nm)
defshowname(self):
print('Yournameis',self.name)
print('Mynameis',self.__class__.__name__)
defshowver(self):
print(self.version)
defaddMe2Me(self,x):
returnx+x
使用class关键字定义类。
可以提供一个可选的父类或者说基类,如果没有合适的基类,那就可以使用object作为基类。
Class行之后是可选的文档字符串,静态成员定义,及方法定义。
在上面的类中,我们定义了一个静态变量version,它将被所有势力及四个方法共享,__init__(),showname(),.showver(),addMe2Me().这些show*()方法并没有做什么有用的事情,仅仅输出对应的信息。
__init__()方法有一个特殊名字,所有名字开始和结束都有两个下划线的方法都是特殊方法。
当一个类实例被创建时,__init__()方法会自动执行,在类实例创建完毕后执行,类似构建函数。
__init__()可以被当成构建函数,不过不象其它语言中的构建函数,它并不创建例--它仅仅是你的对象创建后执行的第一个方法。
它的目的是执行一些该对象的必要的初始化工作。
通过创建自己的__init__()方法,你可以覆盖默认的__init__()方法(默认的方法什么也不做),从而能够修饰刚刚创建的对象。
在这个例子里,我们初始化了一个名为name的类实例属性(或者说成员)。
这个变量仅在类实例中存在,它并不是实际类本身的一部分。
__init__()需要一个默认的参数,前一节中曾经介绍过。
毫无疑问,你也注意到每个方法都有的一个参数,self.
什么是self?
它是类实例自身的引用。
其他语言通常使用一个名为this的标识符。
当一个实例被创建,__init__()就会被自动调用。
不管这个__init__()是自定义的还是默认的。
>>>foo1=FooClass()
CreatedaclassinstanceforJohnDoe
>>>foo1.showname()
YournameisJohnDoe
MynameisFooClass
>>>foo1.showver()
0.1
>>>print(foo1.addMe2Me(5))
10
>>>importsys
>>>sys.stdout.write('HelloWorld!
\n')
HelloWorld!
13
>>>sys.platform
'win32'
变量赋值:
变量赋值并不是直接将一个值赋给一个变量。
对象是通过引用传递的。
在赋值时,不管这个对象是新创建的,还是一个已经存在的,都是将该对象的引用(并不是值)赋值给变量。
_xxx不用'frommoduleimport*'导入
__xxx__系统定义名字
__xxx类中的私有变量名
模块结构和布局:
#
(1)起始行(Unix)
#
(2)模块文档
#(3)模块导入
#(4)变量定义
#(5)类定义
#(6)函数定义
#(7)主程序
模块文档:
简要介绍模块的功能及重要全局变量的含义,模块外可通过module.__doc__访问这些内容。
(3)模块导入
导入当前模块的代码需要的所有模块;每个模块仅导入一次(当前模块被加载时);函数
内部的模块导入代码不会被执行,除非该函数正在执行。
(4)变量定义
这里定义的变量为全局变量,本模块中的所有函数都可直接使用。
从好的编程风格角度说,
除非必须,否则就要尽量使用局部变量代替全局变量,如果坚持这样做,你的代码就不但容易维护,而且还可以提高性能并节省内存。
(5)类定义语句
所有的类都需要在这里定义。
当模块被导入时class语句会被执行,类也就会被定义。
类
的文档变量是class.__doc__。
(6)函数定义语句
此处定义的函数可以通过module.function()在外部被访问到,当模块被导入时def语句
会被执行,函数也就都会定义好,函数的文档变量是function.__doc__。
(7)主程序
无论这个模块是被别的模块导入还是作为脚本直接执行,都会执行这部分代码。
通常这里
不会有太多功能性代码,而是根据执行的模式调用不同的函数。
__name__指示模块应如何被加载
如果模块是被导入,__name__的值为模块名字
如果模块是被直接执行,__name__的值为'__main__'
Python标准库中还提供了unittest模块,有时候它被称为PyUnit,是一个测试框架
要保持追踪内存中的对象,Python使用了引用计数这一简单技术。
也就是说Python内部
记录着所有使用中的对象各有多少引用。
你可以将它想像成扑克牌游戏“黑杰克”或“21点”。
一个内部跟踪变量,称为一个引用计数器。
至于每个对象各有多少个引用,简称引用计数。
当对象被创建时,就创建了一个引用计数,当这个对象不再需要时,也就是说,这个对象的引用计数变为0时,它被垃圾回收。
一个对象的引用计数在以下情况会减少:
一个本地引用离开了其作用范围。
比如foobar()(参见上一下例子)函数结束时。
对象的别名被显式的销毁。
dely#ordelx
对象的一个别名被赋值给其它的对象
x=123
对象被从一个窗口对象中移除
myList.remove(x)
窗口对象本身被销毁
delmyList#orgoesout-of-scope
将经常用到的模块属性替换为一个本地引用
创建文件(makeTextFile.py)
#!
/usr/bin/env/python
'makeTextFile.py--createtextfile'
importos
ls=os.linesep
#getfilename
whileTrue:
ifos.path.exists(fname):
print("ERROR:
'%s'alreadyexists"%fname)
else:
break
#getfilecontentlines
all=[]
print("\nEnterlines('.'byitselftoquit).\n")
whileTrue:
entry=input('>')
ifentry=='.':
break
else:
all.append(entry)
fobj=open(fname,'w')
fobj.writelines(['%s%s'%(x,ls)forxinall])
fobj.close()
print('DONE')
所有的Python对像都拥有三个特性:
身份,类型和值。
身份:
每一个对象都有一个唯一的身份标识自己,任何对象的身份可以使用内建函数id()来得到。
这个值可以被认为是该对象的内存地址。
您极少会用到这个值,也不用太关心它究竟是什么。
类型
对象的类型决定了该对象可以保存什么类型的值,可以进行什么样的操作,以及遵循什么样的规则。
您可以用内建函数type()查看Python对象的类型。
因为在Python中类型也是对象
(还记得我们提到Python是面向对象的这句话吗?
),所以type()返回的是对象而不是简单的
字符串。
值
对象表示的数据项
所有类型对象的类型都是type
Python有一个特殊的类型,被称作Null对象或者NoneType,它只有一个值,那就是None。
None没有什么有用的属性,它的布尔值总是False。
代码对象是编译过的Python源代码片段,它是可执行对象。
通过调用内建函数compile()
可以得到代码对象。
代码对象可以被exec命令或eval()内建函数来执行。
帧对象表示Python的执行栈帧。
帧对象包含Python解释器在运行时所需要知道的所有信
息。
它的属性包括指向上一帧的链接,正在被执行的代码对象(参见上文),本地及全局名字空间字典以及当前指令等。
每次函数调用产生一个新的帧,每一个帧对象都会相应创建一个C栈帧。
用到帧对象的一个地方是跟踪记录对象
当你的代码出错时,Python就会引发一个异常。
当异常发生时,一个包含针对异常的栈跟踪信息的跟踪记录对象被创建。
如果一个异常有
自己的处理程序,处理程序就可以访问这个跟踪记录对象。
括步进切片,多维切片,及省略切片。
多维切片语法是sequence[start1:
end1,
start2:
end2],或使用省略号,sequence[...,start1:
end1].切片对象也可以由内建
函数slice()来生成。
步进切片允许利用第三个切片元素进行步进切片,它的语法为sequence[起始索引:
结束索引:
步进值]
>>>foostr='abcde'
>>>foostr[:
:
-1]
'edcba'
>>>foostr[:
:
-2]
'eca'
>>>foolist=[123,'xba',342.23,'abc']
>>>foolist[:
:
-1]
['abc',342.23,'xba',123]
省略对象用于扩展切片语法中,起记号作用。
这个对象在切片语法中表示省略号。
类似
Null对象None,省略对象有一个唯一的名字Ellipsis,它的布尔值始终为True.
调用内建函数xrange()会生成一个Xrange对象,xrange()是内建函数range()的兄弟版
本,用于需要节省内存使用或range()无法完成的超大数据集场合。
3<4<7#sameas(3<4)and(4<7)
Python提供了is和isnot运算符来测试两个变量是否指向同一个对象。
aisb
这个表达式等价于下面的表达式
id(a)==id(b)
>>>a=[5,'hat',-9.3]
>>>b=a
>>>aisb
True
>>>aisnotb
False
整数对象和字符串对象是不可变对象,所以Python会很高效的缓存它们。
这会造成我们认为Python应该创建新对象时,它却没有创建新对象的假象。
>>>a=1
>>>b=1
>>>aisb
True
>>>id(a)
507081216
>>>id(b)
507081216
>>>c=1.0
>>>id(c)
32898168
>>>d=1.0
>>>id(d)
32898192
Python仅缓存简单整数,因为它认为在Python应用程序中这些小整数会经常被用到
标准类型内建函数
Python提供了一些内建函数用于这些基本对象类型:
cmp(),repr(),str(),type(),和等同于repr()函数的单反引号(``)运算符。
函数功能
repr(obj)或`obj`返回一个对象的字符串表示
str(obj)返回对象适合可读性好的字符串表示
type(obj)得到一个对象的类型,并返回相应的type对象
>>>str
(1)
'1'
>>>str(2e10)
'20000000000.0'
>>>str([0,5,9,9])
'[0,5,9,9]'
>>>repr([0,5,9,9])
'[0,5,9,9]'
>>>'[0,5,9,9]'
'[0,5,9,9]'
事实上repr()和``做的是完全一样的事情,它们返回的是一个对象的“官方”字符串表示,也就是说绝大多数情况下可以通过求值运算(使用eval()内建函数)重新得到该对象,但str()则有所不同。
str()致力于生成一个对象的可读性好的字符串表示,它的返回结果通常无法用于eval()求值,但很适合用于print语句输出。
需要再次提醒一下的是,并不是所有repr()返回的字符串都能够用eval()内建函数得到原来的对象:
#!
/usr/bin/envpython
defdisplayNumType(num):
print(num,'is')
ifisinstance(num,(int,float,complex)):
print('anumberoftype:
',type(num).__name__)
else:
print('notanumberatall!
!
')
displayNumType(-69)
displayNumType(98.6)
displayNumType(-5.2+1.9j)
displayNumType('xxx')
defdisplayNumType(num):
print(num,"is",)
iftype(num)==type(0):
print('aninteger')
eliftype(num)==type(0.0):
print('afloat')
eliftype(num)==type(0+0j):
print('acomplexnumber')
else:
print('notanumberatall!
!
')
displayNumType(-69)
displayNumType(98.6)
displayNumType(-5.2+1.9j)
displayNumType('xxx')
如果让我们最啰嗦的描述标准类型,我们也许会称它们是Python的“基本内建数据对象原
始类型”。
“基本”,是指这些类型都是Python提供的标准或核心类型。
“内建”,是由于这些类型是Python默认就提供的
“数据”,因为他们用于一般数据存储
“对象”,因为对象是数据和功能的默认抽象
“原始”,因为这些类型提供的是最底层的粒度数据存储
“类型”,因为他们就是数据类型
我们对类型进行分类的第一种方式,就是看看这种类型的对象能保存多少个对象。
Python
的类型,就象绝大多数其它语言一样,能容纳一个或多个值。
一个能保存单个字面对象的类型我们称它为原子或标量存储,那些可容纳多个对象的类型,我们称之为容器存储。
(容器对象有时会在文档中被称为复合对象,不过这些对象并不仅仅指类型,还包括类似类实例这样的对象)容器类型又带来一个新问题,那就是它是否可以容纳不同类型的对象。
所有的Python容器对象都能够容纳不同类型的对象.
存储模型
分类Python类型
标量/原子类型数值(所有的数值类型),字符串(全部是文字)
容器类型列表、元组、字典
另一种对标准类型进行分类的方式就是,针对每一个类型问一个问题:
“对象创建成功之
后,它的值可以进行更新吗?
”
新创建的对象被关联到原来的变量名,旧对象被丢弃,垃圾回收器会在适当的时机回收这
些对象.
更新模型
分类Python类型
可变类型列表,字典
不可变类型数字、字符串、元组
>>>x='Pythonnumbersandstrings'
>>>print(id(x))
50252176
>>>x='areimmutable?
!
?
Whatgives?
'
>>>print(id(x))
50252016
>>>i=0
>>>print(id(i))
507081184
>>>i=i+1
>>>print(id(i))
507081216
>>>aList=['ammonia',83,85,'lady']
>>>aList
['ammonia',83,85,'lady']
>>>aList[2]
85
>>>id(aList)
50034696
>>>aList[2]=aList[2]+1
>>>aList[3]='stereo'
>>>aList
['ammonia',83,86,'stereo']
>>>id(aList)
50034696
>>>aList.append('gaudy')
>>>aList.append(aList[2]+1)
>>>aList
['ammonia',83,86,'stereo','gaudy',87]
>>>id(aList)
50034696
也就是说根据访问我们存储的数据的方式对数据类型进行分类。
在访问模型中共有三种访问方式:
直接存取,顺序,和映射。
对非容器类型可以直接访问。
所有的数值类型都归到这一类。
序列类型是指容器内的元素按从0开始的索引顺序访问。
一次可以访问一个元素或多个元
素,也就是大家所了解的切片(slice)。
字符串,列表和元组都归到这一类。
映射类型类似序列的索引属性,不过它的索引并不使用顺序的数字偏移量取值,它的元素
无序存放,通过一个唯一的key来访问,这就是映射类型,它容纳的是哈希键-值对的集合。
访问模型
分类Python类型
直接访问数字
顺序访问字符串、列表、元组
映射访问字典
数字提供了标量贮存和直接访问。
它是不可更改类型,也就是说变更数字的值会生成新的
对象.
>>>aComplex=1.23+4.56J
>>>aComplex
(1.23+4.56j)
通过给数字对象(重新)赋值,您可以“更新”一个数值对象。
我们之所以给更新这两个
字加上引号,是因为实际上你并没有更新该对象的原始数值。
这是因为数值对象是不可改变对象。
Python的对象模型与常规对象模型有些不同。
你所认为的更新实际上是生成了一个新的数值对象,并得到它的引用。
虚数不能单独存在,它们总是和一个值为0.0的实数部分一起来构成一个复数。
复数由实数部分和虚数部分构成
表示虚数的语法:
real+imagj
实数部分和虚数部分都是浮点数
虚数部分必须有后缀j或J。
属性描述
num.real该复数的实部
numnum.imag该复数的虚部
num.conjugate()返回该复数的共轭复数
>>>x=4+1j
>>>x
(4+1j)
>>>x.conjugate()
(4-1j)
>>>x.real
4.0
>>>x.imag
1.0
整数转换为浮点数,非复数转换为复数。
如果有一个操作数是复数,另一个操作数被转换为复数。
否则,如果有一个操作数是浮点数,另一个操作数被转换为浮点数。
一个新的运算符//已经被增加进来,以执行地板除:
//除法不管操作数何种数值类型,总是舍去小数部分,返回数字序列中比真正的商小的最接近的数字。
>>>1/2
0.5
>>>1//2
0
>>>2//3
0
>>>4//3
1
>>>-4//3
-2
divmod()内建函数把除法和取余运算结合起来,返回一个包含商和余数的元组。
对整数来
说,它的返回值就是地板除和取余操作的结果。
对浮点数来说,返回的商部分是
math.floor(num1/num2),对复数来说,商部分是ath.floor((num1/num2).real)。
>>>divmod(10,3)
(3,1)
>>>divmod(3,10)
(0,3)
>>>divmod(10,2.5)
(4.0,0.0)
内建函数round()用于对浮点数进行四舍五入运算。
它有一个可选的小数位数参数。
如果
不提供小数位参数,它返回与第一个参数最接近的整数(但仍然是浮点类型)。
第二个参数告诉round函数将结果精确到小数点后指定位数。
>>>round(3)
3
>>>round(3.45)
3
>>>round(3.49999)
3
>>>round(3.49999,1)
3.5
>>>round(-3.4)
-3
>>>round(-3.5)
-4
>>>round(-3.49,1)
-3.5
round()函数是按四舍五入的规则进行取整
函数floor()得到最接近原数但小于原数的整数
函数int()直接截去小数部分。
Python还提供了两个内建函数来返回字符串表示的8进制和16进制整数。
它们分别是oct()和hex()。
>>>hex(255)
'0xff'
>>>oct(255)
'0o377'
函数chr()接受一个单字节整数