编辑器:windows,linux
不要用notepad,缩进糟糕
--------------
5.18缩进
同一层次的语句必须有相同的缩进。每一组这样的语句称为一个块。
1i = 5
2 print('Value is ', i)# Error! Notice a single space at the start
of the line行首有空格
3print('I repeat, the value is ', i)
当你运行的时候,会得到下面的出错信息:
1File "whitespace.py", line 4
2print('Value is ', i) # Error! Notice a single space at the start
of the line
3^
4IndentationError: unexpected indent
-------------
如何缩进
不要混合使用制表符和空格来缩进,因为这在跨越不同的平台的时候,无法正常工作。我强烈建
议你在每个缩进层次使用单个制表符或两个或四个空格。
----------
给静态语言程序员的注释:
Python总是使用缩进来代表代码块,不再使用括号。
--------------------------------------------------------------------------------
第七章 控制流
7.2 if语句
#!/usr/bin/python
2# Filename: if.py
3
4number = 23
5guess =int(input('Enter an integer : '))
6
7ifguess == number:
8print('Congratulations, you guessed it.')# New block starts
here
9print('(but you do not win any prizes!)')# New block ends here
10elifguess < number:
11print('No, it is a little higher than that')# Another block
12# You can do whatever you want in a block ...
13else:
14print('No, it is a little lower than that')
15# you must have guess > number to reach here
16print('Done')
17# This last statement is always executed, after the if statement is
executed
-----------
注意:input()与raw_input()的区别
网上:前者可以计算数值,后者表示字符串
--------------
最简单的有效if语句是:
1ifTrue:
2print('Yes, it is true')
---------------------------------
while语句
# !/usr/bin/python
2# Filename while.py
3
4number = 23
5running =True
6
7whilerunning:
8guess=int(input("Enter an integer:"))
9
10ifguess == number:
11print("Congratulation, you guessed it.")
12running=False#this causes the while loop to stop
13elifguess < number:
14print("No, it is a little higher.")
15else:
16print("No, it is a little lower.")
17else:
18print("the while loop is over.")
19# Do anything else you want to do here
20
21print("done")
输出:
1$ python while.py
2Enter an integer : 50
3No, it is a little lower than that.
4Enter an integer : 22
5No, it is a little higher than that.
6Enter an integer : 23
7Congratulations, you guessed it.
8The while loop is over.
9Done
-------------------
7.4 for循环
#!/usr/bin/python
2# Filename: for.py
3
4foriinrange ( 1 , 5 ):
5print(i)
6else:
7print('The for loop is over')
输出:
1$ python for.py
21
32
43
54
6The for loop is over
-------------
这个序列从第一个数开
始到第二个数为止。例如,range(1,5)给出序列[1, 2, 3, 4]。默认地,range的步长
为1。如果我们为range提供第三个数,那么它将成为步长。例如,range(1,5,2)给出
[1,3]。记住,range向上延伸到第二个数,即它不包含第二个数。
--------------
在C/C++中,如果你想要写for (int i = 0; i < 5; i++),那么用Python,你写成for i in
range(0,5)。
-------------
7.5 break语句
break语句是用来终止循环语句的,即哪怕循环条件没有变为False或序列还没有
被完全迭代结束,也停止执行循环语句。
一个重要的注释是,如果你从for或while循环中终止,任何对应的循环else块
将不执行。
#!/usr/bin/python
2# Filename: break.py
3
4whileTrue:
5s = (input('Enter something : '))
6ifs =='quit':
7break
8print('Length of the string is', len(s))
9print('Done')
输出:
1$ python break.py
2Enter something : Programming is fun
3Length of the string is 18
4Enter something : When the work is done
5Length of the string is 21
6Enter something : if you wanna make your work also fun:
7Length of the string is 37
8Enter something : use Python!
9Length of the string is 12
10Enter something : quit
11Done
-------------------------
7.7 continue语句
continue语句被用来告诉Python跳过当前循环块中的剩余语句,然后继续进行下
一轮循环。
-----------------------------------------------------------------------------
第八章函数
函数用关键字def来定义。def关键字后跟一个函数的标识符名称,然后跟一对
圆括号。圆括号之中可以包括一些变量名,该行以冒号结尾。接下来是一块语句,它
们是函数体。
defsayHello():
5print('Hello World!')# block belonging to the function
6# End of function
7sayHello()# call the function
8sayHello()# call the function again
----------------
8.2 函数的参数
defprintMax(a,b):
5 ifa > b:
6 print(a,'is maximum')
7 elifa == b:
8 print(a,'is equal to',b)
9 else:
10 print(b,'is maximum')
printMax(3,4)# directly give literal valuse
x = 5
y = 7
printMax(x,y)# give variables as arguments
在第一个printMax使用中,我们直接把数,即实参,提供给函数。在第二个使用
中,我们使用变量调用函数。printMax(x,y)使实参x的值赋给形参a,实参y的值赋
给形参b。
-------------------
8.4使用全局语句
没有global语句,是不可能为定义在函数外的变量赋值的。
1#!/usr/bin/python
2#Filename: func_global.py
3
4x = 50
5
6deffunc():
7globalx
8
9print('x is',x)
10x = 2
11print('Changed global x to',x)
12
13func()
14print('Value of x is',x)
-------------
global语句被用来声明x是全局的——因此,当我们在函数内把值赋给x的时
候,这个变化也反映在我们在主块中使用x的值的时候。
你可以使用同一个global语句指定多个全局变量。例如global x, y, z。
-------------
8.5使用非局部语句(nonlocal)(3.X的特性)
非局部作用域在你定义函数内的函数时会看到。
由于在Python中,任何事物是可执行的代码,你可以在任何地方定义函数。
#!/usr/bin/python
2# Filename: func_nonlocal.py
3
4deffunc_outer():
5x = 2
6print('x is',x)
7
8deffunc_inner():
9nonlocalx
10x = 5
11
12func_inner()
13print('Changed local x to',x)
14
15func_outer()
-------------
nonlocal的理解:局部内的全局语句。
在外函数中定义了一个局部变量,当在外函数内部再建立一个内函数,并想让内函数内的变量在整个外函数内是全局的,
就可以用nonlocal
-------------------------------
8.6默认参数值
在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。
注意,默认参数值应该是一个参数。更加准确的说,默认参数值应该是不可变的
4defsay(message, times = 1):
5print(message * times)
6
7say('Hello')
8say('World', 5)
输出:
1$ python func_default.py
2Hello
3WorldWorldWorldWorldWorld
-------------------
重要的:
只有在形参表末尾的那些参数可以有默认参数值,即你不能在声明函数形参的时候,先声明有默
认值的形参而后声明没有默认值的形参。这是因为赋给形参的值是根据位置而赋值的。例如,def
func(a, b=5)是有效的,但是def func (a=5, b)是无效的。
------------------------
8.7关键参数
如果某个函数有许多参数,而你只想指定其中的一部分,可以通过命名来为这些参数赋值——这被称作关键参数——我们使用名字(关键字)而不是位置(我们前面所一直使用的方法)来给函数指定实参。
4deffunc(a, b=5, c=10):
5print('a is', a,'and b is', b,'and c is', c)
6
7func(3, 7)
8func(25, c=24)
9func(c=50, a=100)
-------------
8.8 VarArgs参数
定义一个能获取任意个数参数的函数,这可通过使用*号来实现。
4deftotal(initial=5, *numbers, **keywords):
5count = initial
6fornumberinnumbers:
7count += number
8forkeyinkeywords:
9count += keywords[key]
10returncount
11
12print(total(10, 1, 2, 3, vegetables=50, fruits=100))
----------------
8.10 return语句
4defmaximum(x, y):
5ifx > y:
6returnx
7else:
8returny
9
10print(maximum(2, 3))
注意,没有返回值的return语句等价于return None。None是Python中表示没有任何东西的特殊类型。
---------------
8.11 DocStrings
文档字符串,它通常被简称为docstrings。
DocStrings是一个重要的工具,由于它帮助你的程序文档更加简单易懂
在函数的第一个逻辑行的字符串是这个函数的文档字符串。
文档字符串的惯例是一个多行字符串,它的首行以大写字母开始,句号结尾。第
二行是空行,从第三行开始是详细的描述。
你可以使用__doc__(注意双下划线)调用printMax函数的文档字符串属性(属
于函数的名称)。请记住Python把每一样东西都作为对象
def fun():
'''the doc of fun,fun is also an abstract,can use in help()'''
global x #state overall var by using global var in fun
x=2
print "x is:",x,"\n"
x=50
print "x is:",x,"\n"
print "After going to fun:\n"
fun()
print fun.__doc__
shell中运行:
>>help(fun)
Help on function fun in module __main__:
fun()
the doc of fun,fun is also an abstract
---------------------------------------------------------------
第九章模块
#!/usr/bin/python
# Filename: using_sys.py
import
sys
print
'The command line arguments are:'
for
i
in
sys
.argv:
print
i
print
'\n\nThe PYTHONPATH is'
,
sys
.path,
'\n'
sys
模块包含了与Python解释器和它的环境有关的函数。
如果它是未编译的模块,如用Python写的模块,Python解释器会查找列
在sys.path变量中的路径。如果模块找到了,就会运行那个模块主体中的语句,
模块就是可以利用的了。
在sys模块中,argv变量可以用sys.argv来引用。它很清楚地表明这个名字
是sys模块中的一部分。这种方法的一个优势是这个名称不会与任何在你的程序中使
用的argv变量冲突。
记住,脚本的名称总是sys.argv列表的第一个参数。所以,在这里,’using_sys.py’
是sys.argv[0]、’we’是sys.argv[1]、’are’是sys.argv[2]以及’arguments’是sys.argv[3]。
-----------------
9.3 from...import...语句
如果你想要直接输入argv变量到你的程序中(避免在每次使用它时打sys.),那
么你可以使用from sys import argv语句。如果你想要输入所有sys模块使用的名字,
那么你可以使用from sys import *语句。
--
.pyc文件:字节编译的文件。他已经完成了一部分模块的处理,下次运行会更快,而且与平台无关。
--------------
9.4模块的__name__
每个模块都有一个名称,在模块中可以通过语句来找出模块的名称。
当一个模块被第一次输入的时候,这个模块的
主块将被运行。假如我们只想在程序本身被使用的时候运行主块,而在它被别的模块
输入的时候不运行主块,我们该怎么做呢?这可以通过模块的__name__属性完成。
例子:
1#!/usr/bin/python
2# Filename: using_name.py
3
4if__name__ =='__main__':
5print('This program is being run by itself')
6else:
7print('I am being imported from another module')
输出:
1$ python using_name.py
2This program is being run by itself
3$ python
4>>> import using_name
5I am being imported from another module
如何工作:
每个Python模块都有它的__name__,如果它是’__main__’,这说明这个模块被
用户单独运行,我们可以进行相应的恰当操作。
--------
9.5创建自己的模块(***)
模块应该被放置在我们输入它的程序的同一个目录中,或者在sys.path
所列目录之一。
#第一个例子
#!/usr/bin/python
# Filename: mymodule.py
def
sayhi
():
print
'Hi, this is mymodule speaking.'
version =
'0.1'
# End of mymodule.py
#第二个例子
#!/usr/bin/python
# Filename: mymodule_demo.py
import
mymodule
mymodule.sayhi()
print
'Version'
, mymodule.version
输出:
1$ python mymodule_demo.py
2Hi, this is mymodule speaking.
3Version 0.1
第二个版本:
3
4frommymoduleimportsayhi, __version__
5
6sayhi()
7print('Version', __version__)
如果已经在导入mymodule的模块中申明了一个__version__的名字,这就
会有冲突。这也是有可能的,因为从实际情况来看,每个模块会用这个名字来申明它
的版本。因此,推荐选择使用import语句,虽然会导致程序稍微有点冗长。
你也可以这样使用:
1frommymoduleimport*
这会导入像sayhi这样公用的名字,但不会导入__version__,因为它是以双下划
线开始的。
--------------
9.6 dir函数
使用内建的dir函数来列出模块定义的标识符。标识符有函数、类和变量。
当你为dir()提供一个模块名的时候,它返回模块定义的名称列表。如果不提供
参数,它返回当前模块中定义的名称列表。
1$ python
2>>>importsys# get list of attributes, in this case, for the sys
module
3>>> dir(sys)
4['__displayhook__','__doc__','__excepthook__','__name__',
5'__package__','__s
6tderr__','__stdin__','__stdout__','_clear_type_cache',
……………………………………
27>>> dir()# get list of attributes for current module
28['__builtins__','__doc__','__name__','__package__','sys']
29>>> a = 5# create a new variable 'a'
30>>> dir()
31['__builtins__','__doc__','__name__','__package__','a','sys']
32>>>dela# delete/remove a name
33>>> dir()
34['__builtins__','__doc__','__name__','__package__','sys']
---------------
9.7包
包是模块的文件夹,有一个特殊的__init__.py文件,用来表明这个文件夹是特殊
的因为其包含有Python模块。
假如你想创建一个叫做’world’的包,有子包’asia’,’africa’等等,并且,这些子包
又包含模块,如’india’,’madagascar’等等。
这就是你想构造的文件夹:
---------------
第十章:数据结构
python的三种内建数据结构:列表、元组、字典。
序列、应用、字符串
列表(list)是处理一组有序项目的数据结构,在每个项目之间用逗号分割。
如:shoplist=['apple','carrot','banana']
列表 是 可变的 数据类型。
类的函数append(),在列表尾添加项目,用法是mylist.append('string')
列表也是序列,可以使用del()删除某个元素,用sort()排序会影响列表本身。
元组和列表相似,但是不可修改。
元组通过圆括号中用逗号分割的项目定义。通常用在使语句或用户定义的函数能够安全地采用一组值的时候。
如:zoo = ('lion','tiger','panda')
包含0个元素的元组是tuple=(),包含2个元素的元组是tuple=(2,)
字典:把键(名字)和 值(详细情况)联系在一起。
如:dictionary={key1:value1,key2:value2}
取值:dictionary[key1]
注意,键必须是唯一的。键不可变。值可以变。
字典没有顺序。del可以删除字典的每个键值对。
序列:列表、元组和字符串都是序列。
序列的两个主要特点是索引操作符和切片操作符。
索引操作符让我们可以从序列中抓取一个特定项目。切片操作 符让我们能够获取序列的一个切片,即一部分序列。
对象与引用:
创建一个对象并给它赋一个变量时,这个变量仅仅 引用 那个对象,而不是表示这个 对象本身!
也就是,变量名指向你计算机中存储那个对象的内存。这被称作名称到对象的绑定。
字符串:
str类有以一个作为分隔符的字符串join序列的项目的整洁的方法,它返回一个生成的大字符串。
---------------
第十一章:解决问题
编写一个压缩备份程序
---------------
第十二章:面向对象编程
对象可以使用普通的属于对象的变量存储数据。属于一个对象或类的变量被称为域。
对象也可以使用属于类的函数来具有功能。这样的函数被称为类的方法。
这些术语帮助我们把它们与孤立的函数和变量区分开来。域和方法可以合称为类的属性。
域有两种类型——属于每个实例/类的对象或属于类本身。它们分别被称为实例变量和类变量。
类使用class 关键字创建。类的域和方法被列在一个缩进块中。
-------
12.2 self
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,
但是在调用这个方法的时候你不为这个参数赋值,Python会提供这个值。
这个特别的变量指对象本身,按照惯例它的名称是self。
12.3类
一个尽可能简单的类如下面这个例子所示。
1#!/usr/bin/python
2# Filename: simplestclass.py
3
4classPerson:
5pass# An empty block
6
7p = Person()
8print(p)
输出:
1$ python simplestclass.py
2<__main__.Person object at 0x019F85F0>
我们使用class语句后跟类名,创建了一个新的类。这后面跟着一个缩进的语句
块形成类体。在这个例子中,我们使用了一个空白块,它由pass语句表示。
接下来,我们使用类名后跟一对圆括号来创建一个对象/实例。
classPerson:
5defsayHi(self):
6print('Hello, how are you?')
7
8p = Person()
9p.sayHi()
10# This short example can also be written as Person().sayHi()
输出:
1$ python method.py
2Hello, how are you?
12.5 __init__方法
__init__方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对
象做一些你希望的初始化。注意,这个名称的开始和结尾都是双下划线。
1#!/usr/bin/python
2# Filename: class_init.py
3
4classPerson:
5def__init__(self, name):
6self.name = name
7defsayHi(self):
8print('Hello, my name is',self.name)
9
10p = Person('Swaroop')
11p.sayHi()
把__init__方法定义为取一个参数name(以及普通的参数self)。在
这个__init__里,我们只是创建一个新的域,也称为name。注意它们是两个不同的
变量,尽管它们有相同的名字。点号使我们能够区分它们。
最重要的是,我们没有专门调用__init__方法,只是在创建一个类的新实例的时
候,把参数包括在圆括号内跟在类名后面,从而传递给__init__方法。这是这种方法
的重要之处。
__init__方法相当于C++,Java,C#中的构造函数
-----------------
12.6类和对象变量(!!!???)
有两种类型的域——类的变量和对象的变量,它们根据是类还是对象拥有这个变量而区分。
类的变量由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,所以
当某个对象对类的变量做了改动的时候,这个改动会反映到所有其他的实例上。
对象的变量由类的每个对象/实例拥有。因此每个对象有自己对这个域的一份拷
贝,即它们不是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称,
但是是互不相关的。
Python中所有的类成员(包括数据成员)都是 公共的 ,所有的方法都是 有效的 。
如果你使用的数据成员名称以 双下划线前缀 比如__privatevar
,Python的名称管理体系会有效地把它作为私有变量。
这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他的名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求的(与双下划线前缀不同)。
同样,注意__del__
方法与 destructor 的概念类似。
#!/usr/bin/python
# Filename: objvar.py
class
Person
:
'''Represents a person.'''
population =
0
def
__init__
(self, name):
'''Initializes the person's data.'''
self.name = name
print
'(Initializing %s)'
% self.name
# When this person is created, he/she
# adds to the population
Person.population +=
1
def
__del__
(self):
'''I am dying.'''
print
'%s says bye.'
% self.name
Person.population -=
1
if
Person.population ==
0
:
print
'I am the last one.'
else
:
print
'There are still %d people left.'
% Person.population
def
sayHi
(self):
'''Greeting by the person.
Really, that's all it does.'''
print
'Hi, my name is %s.'
% self.name
def
howMany
(self):
'''Prints the current population.'''
if
Person.population ==
1
:
print
'I am the only person here.'
else
:
print
'We have %d persons here.'
% Person.population
swaroop = Person(
'Swaroop'
)
swaroop.sayHi()
swaroop.howMany()
kalam = Person(
'Abdul Kalam'
)
kalam.sayHi()
kalam.howMany()
swaroop.sayHi()
swaroop.howMany()
-------------------------------------------------------
????????????????
对象和类的例子
C:\Python27\test\ObjVarRobot.py
关于staticmathod():
1\staticmethod 基本上和一个全局函数差不多,只不过可以通过类或类的实例对象(python里光说对象总是容易产生混淆, 因为什么都是对象,包括类,而实际上类实例对象才是对应静态语言中所谓对象的东西)来调用而已, 不会隐式地传入任何参数。这个和静态语言中的静态方法比较像。
2\classmethod 是和一个class相关的方法,可以通过类或类实例调用,并将该class对象(不是class的实例对象)隐式地 当作第一个参数传入。就这种方法可能会比较奇怪一点,不过只要你搞清楚了python里class也是个真实地 存在于内存中的对象,而不是静态语言中只存在于编译期间的类型。
3\另一种写法
@staticmethod
defhowMany():
……………………
如何工作:
(???)
population属于Robot类,因此是一个类变量。name变量属于对象(用self给其赋值),因此是一
个对象变量。
因此,我们使用Robot.population来引用population类变量,而不是用self.population
来引用。我们在该对象的方法中用self.name来引用对象变量name。记住类和对象变
量之间这个简单的差别。也要注意一个与类变量有相同名字的对象变量会隐藏类变
量!
howMany实际上是属于类而不是对象的方法。这意味着我们或者可以定义类方
法或者可以定义静态方法,这取决于我们是否需要知道我们是那个类的部分。既然我
们不需要这样的信息,就需要将其定义为静态方法。
必须仅用self来引用同一对象的变量和方法。这叫属性参考。
在这个程序中,也看到了和方法一样在类中使用docstrings。我们可以在运行的
时候使用Robot.__doc__来获得类的docstring,用Robot.sayHi.__doc__来获得方法的
docstring。
就如同__init__方法一样,还有一个特殊的方法__del__,它在对象消逝的时候
被调用。对象消逝即对象不再被使用,它所占用的内存将返回给系统作它用。在这个
方法里面,我们只是简单地把Person.population减1。
当对象不再被使用时,__del__方法运行,但是很难保证这个方法究竟在什么时
候运行。如果你想要指明它的运行,你就得使用del语句,就如同我们在以前的例子
中使用的那样。
给C++/Java/C#程序员的注释:
Python中所有的类成员(包括数据成员)都是公共的,所有的方法都是有效的。
只有一个例外:如果你使用的数据成员名称以双下划线前缀比如__privatevar,Python的名称
管理体系会有效地把它作为私有变量。
这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他
的名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求
的(与双下划线前缀不同)。
????????????????????
---------------------------------------------------
12.7继承
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过 继承 机制。
如果为教师和学生两个独立的类添加共同的属性,比较好的方法是创建一个共同的类称为SchoolMember。
然后让教师和学生的类 继承 这个共同的类。即它们都是这个类型(类)的子类型,然后我们再为这些子类型添加专有的属性。
优点是,如果增加/改变了SchoolMember
中的功能,它会自动地反映到子类中。
然而,在一个子类型之中做的改动不会影响到别的子类型。
另外一个优点是你可以把教师和学生对象都作为SchoolMember
对象来使用,这在某些场合特别有用,比如统计学校成员的人数。
一个子类型在任何需要父类型的场合可以被替换成父类型,即对象可以被视作是父类的实例,这种现象被称为多态现象。(???与C++的区别???)
在 重用 父类的代码的时候,无需在不同的类中重复它。而如果我们使用独立的类的话,我们就不得不这么做了。
在上述的场合中,SchoolMember
类被称为 基本类 或 超类 。而Teacher
和Student
类被称为 导出类 或 子类 。
#!/usr/bin/python
# Filename: inherit.py
class
SchoolMember
:
'''Represents any school member.'''
def
__init__
(self, name, age):
self.name = name
self.age = age
print
'(Initialized SchoolMember: %s)'
% self.name
def
tell
(self):
'''Tell my details.'''
print
'Name:"%s" Age:"%s"'
% (self.name, self.age),
class
Teacher
(SchoolMember):
'''Represents a teacher.'''
def
__init__
(self, name, age, salary):
SchoolMember.__init__(self, name, age)
self.salary = salary
print
'(Initialized Teacher: %s)'
% self.name
def
tell
(self):
SchoolMember.tell(self)
print
'Salary: "%d"'
% self.salary
class
Student
(SchoolMember):
'''Represents a student.'''
def
__init__
(self, name, age, marks):
SchoolMember.__init__(self, name, age)
self.marks = marks
print
'(Initialized Student: %s)'
% self.name
def
tell
(self):
SchoolMember.tell(self)
print
'Marks: "%d"'
% self.marks
t = Teacher(
'Mrs. Shrividya'
,
40
,
30000
)
s = Student(
'Swaroop'
,
22
,
75
)
print
# prints a blank line
members = [t, s]
for
member
in
members:
member.tell()
# works for both Teachers and Students
学校成员类的例子:
C:\Python27\inherit.py
Python不会自动调用基本类的constructor,你得亲自显式调用它。
Python总是首先查找对应类型的方法,如果不能在导出类中找到对应的方法,才开始到基本类中逐个查找。
----------------------------------------------------------
第十三章:输入输出
#!/usr/bin/python
# Filename: using_file.py
poem =
'''\
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
'''
f =
file
(
'poem.txt'
,
'w'
)
# open for 'w'riting
f.write(poem)
# write text to file
f.close()
# close the file
f =
file
(
'poem.txt'
)
# if no mode is specified, 'r'ead mode is assumed by default
while
True
:
line = f.readline()
if
len
(line) ==
0
:
# Zero length indicates EOF
break
print
line,
# Notice comma to avoid automatic newline added by Python
f.close()
# close the file
我们首先用写模式打开文件,然后使用file
类的write
方法来写文件,最后我们用close
关闭这个文件。
接下来,我们再一次打开同一个文件来读文件。如果我们没有指定模式,读模式会作为默认的模式。在一个循环中,我们使用readline
方法读文件的每一行。这个方法返回包括行末换行符的一个完整行。所以,当一个 空的 字符串被返回的时候,即表示文件末已经到达了,于是我们停止循环。
注意,因为从文件读到的内容已经以换行符结尾,所以我们在print
语句上使用逗号来消除自动换行。最后,我们用close
关闭这个文件。
储存器pickle:
#!/usr/bin/python
# Filename: pickling.py
import
cPickle
as p
#import pickle as p
shoplistfile =
'shoplist.data'
# the name of the file where we will store the object
shoplist = [
'apple'
,
'mango'
,
'carrot'
]
# Write to the file
f =
file
(shoplistfile,
'w'
)
p.dump(shoplist, f)
# dump the object to a file
f.close()
del
shoplist
# remove the shoplist
# Read back from the storage
f =
file
(shoplistfile)
storedlist = p.load(f)
print
storedlist
为了在文件里储存一个对象,首先以写模式打开一个file
对象,然后调用储存器模块的dump
函数,把对象储存到打开的文件中。这过程称为 储存 。
接下来,我们使用pickle
模块的load
函数的返回来取回对象。这个过程称为 取储存 。
--------------------------------------------------
第十三章
异常
EOFError
的错误,这个错误基本上意味着它发现一个不期望的 文件尾
我们把所有可能引发错误的语句放在try
块中,然后在except
从句/块中处理所有的错误和异常。except
从句可以专门处理单一的错误或异常,或者一组包括在圆括号内的错误/异常。如果没有给出错误或异常的名称,它会处理 所有的 错误和异常。对于每个try
从句,至少都有一个相关联的except
从句。
import
sys
try
:
s =
raw_input
(
'Enter something --> '
)
except
EOFError:
print
'\nWhy did you do an EOF on me?'
sys
.exit()
# exit the program
except
:
print
'\nSome error/exception occurred.'
# here, we are not exiting the program
print
'Done'
引发异常:
你可以使用raise
语句 引发 异常。你还得指明错误/异常的名称和伴随异常 触发的 异常对象。你可以引发的错误或异常应该分别是一个Error
或Exception
类的直接或间接导出类。
#!/usr/bin/python
# Filename: raising.py
class
ShortInputException
(Exception):
'''A user-defined exception class.'''
def
__init__
(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
try
:
s =
raw_input
(
'Enter something --> '
)
if
len
(s) <
3
:
raise ShortInputException(
len
(s),
3
)
# Other work can continue as usual here
except
EOFError:
print
'\nWhy did you do an EOF on me?'
except
ShortInputException, x:
print
'ShortInputException: The input was of length %d, \
was expecting at least %d'
% (x.length, x.atleast)
else
:
print
'No exception was raised.'
假如你在读一个文件的时候,希望在无论异常发生与否的情况下都关闭文件,该怎么做呢?这可以使用finally
块来完成。注意,在一个try
块下,你可以同时使用except
从句和finally
块。
第十四章:标准库
sys有exit、argv等参数
os模块与操作系统和平台相关:
-
os.name
字符串指示你正在使用的平台。比如对于Windows,它是'nt'
,而对于Linux/Unix用户,它是'posix'
。
-
os.getcwd()
函数得到当前工作目录,即当前Python脚本工作的目录路径。
-
os.getenv()
和os.putenv()
函数分别用来读取和设置环境变量。
-
os.listdir()
返回指定目录下的所有文件和目录名。
-
os.remove()
函数用来删除一个文件。
-
os.system()
函数用来运行shell命令。
-
os.linesep
字符串给出当前平台使用的行终止符。例如,Windows使用'\r\n'
,Linux使用'\n'
而Mac使用'\r'
。
-
os.path.split()
函数返回一个路径的目录名和文件名。
>>> os.path.split('/home/swaroop/byte/code/poem.txt')
('/home/swaroop/byte/code', 'poem.txt')
-
os.path.isfile()
和os.path.isdir()
函数分别检验给出的路径是一个文件还是目录。类似地,os.path.existe()
函数用来检验给出的路径是否真地存在。
第十五章:
名称 | 说明 |
__init__(self,...) |
这个方法在新建对象恰好要被返回使用之前被调用。 |
__del__(self) |
恰好在对象要被删除之前调用。 |
__str__(self) |
在我们对对象使用print 语句或是使用str() 的时候调用。 |
__lt__(self,other) |
当使用 小于 运算符(<)的时候调用。类似地,对于所有的运算符(+,>等等)都有特殊的方法。 |
__getitem__(self,key) |
使用x[key] 索引操作符的时候调用。 |
__len__(self) |
对序列对象使用内建的len() 函数的时候调用。 |
使用列表综合:
listone = [
2
,
3
,
4
]
listtwo = [
2
*i
for
i
in
listone
if
i >
2
]
print
listtwo
由于在args
变量前有*
前缀,所有多余的函数参数都会作为一个元组存储在args
中。如果使用的是**
前缀,多余的参数则会被认为是一个字典的键/值对。
当要使函数接收元组或字典形式的参数的时候,有一种特殊的方法,它分别使用*
和**
前缀。
种方法在函数需要获取可变数量的参数的时候特别有用。
由于在args
变量前有*
前缀,所有多余的函数参数都会作为一个元组存储在args
中。如果使用的是**
前缀,多余的参数则会被认为是一个字典的键/值对。
>>> def powersum(power, *args):
... '''Return the sum of each argument raised to specified power.'''
... total = 0
... for i in args:
... total += pow(i, power)
... return total
...
>>> powersum(2, 3, 4)
25
lambda语句:
def
make_repeater
(n):
return lambda
s: s*n
twice = make_repeater(
2
)
print
twice(
'word'
)
print
twice(
5
)
output:
$ python lambda.py
wordword
10
我们使用了make_repeater
函数在运行时创建新的函数对象,并且返回它。lambda
语句用来创建函数对象。本质上,lambda
需要一个参数,后面仅跟单个表达式作为函数体,而表达式的值被这个新建的函数返回。注意,即便是print
语句也不能用在lambda形式中,只能使用表达式。
exec
语句用来执行储存在字符串或文件中的Python语句。
eval
语句用来计算存储在字符串中的有效Python表达式。
assert
语句用来声明某个条件是真的。例如,如果你非常确信某个你使用的列表中至少有一个元素,而你想要检验这一点,并且在它非真的时候引发一个错误,那么assert
语句是应用在这种情形下的理想语句。当assert语句失败的时候,会引发一个AssertionError
。
repr
函数用来取得对象的规范字符串表示。
>>> i = []
>>> i.append('item')
>>> `i`
"['item']"
>>> repr(i)
"['item']"