python读书笔记-《A Byte of Python》中文第三版后半部分

编辑器: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或序列还没有
被完全迭代结束,也停止执行循环语句。
一个重要的注释是,如果你从forwhile循环中终止,任何对应的循环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 NoneNonePython中表示没有任何东西的特殊类型。
---------------
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


importsys

print'The command line arguments are:'
for 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
defsayhi():
    print'Hi, this is mymodule speaking.'
version ='0.1'
# End of mymodule.py
 
#第二个例子
#!/usr/bin/python
# Filename: mymodule_demo.py
importmymodule
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++JavaC#中的构造函数
-----------------
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():
     ……………………
如何工作:
(???)
 populationRobot类,因此是一个类变量。name变量属于对象(用self给其赋值),因此是一
个对象变量。
因此,我们使用Robot.population来引用population类变量,而不是用self.population
来引用。我们在该对象的方法中用self.name来引用对象变量name。记住类和对象变
量之间这个简单的差别。也要注意一个与类变量有相同名字的对象变量会隐藏类变
量!
howMany实际上是属于类而不是对象的方法。这意味着我们或者可以定义类方
法或者可以定义静态方法,这取决于我们是否需要知道我们是那个类的部分。既然我
们不需要这样的信息,就需要将其定义为静态方法。
必须仅用self来引用同一对象的变量和方法。这叫属性参考。
在这个程序中,也看到了和方法一样在类中使用docstrings。我们可以在运行的
时候使用Robot.__doc__来获得类的docstring,用Robot.sayHi.__doc__来获得方法的
docstring
就如同__init__方法一样,还有一个特殊的方法__del__,它在对象消逝的时候
被调用。对象消逝即对象不再被使用,它所占用的内存将返回给系统作它用。在这个
方法里面,我们只是简单地把Person.population1
当对象不再被使用时,__del__方法运行,但是很难保证这个方法究竟在什么时
候运行。如果你想要指明它的运行,你就得使用del语句,就如同我们在以前的例子
中使用的那样。
C++/Java/C#程序员的注释:
Python中所有的类成员(包括数据成员)都是公共的,所有的方法都是有效的。
只有一个例外:如果你使用的数据成员名称以双下划线前缀比如__privatevarPython的名称
管理体系会有效地把它作为私有变量。
这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他
的名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求
的(与双下划线前缀不同)。
????????????????????
---------------------------------------------------
12.7继承

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过 继承 机制。

如果为教师和学生两个独立的类添加共同的属性,比较好的方法是创建一个共同的类称为SchoolMember。

然后让教师和学生的类 继承 这个共同的类。即它们都是这个类型(类)的子类型,然后我们再为这些子类型添加专有的属性。

优点是,如果增加/改变了SchoolMember中的功能,它会自动地反映到子类中。

然而,在一个子类型之中做的改动不会影响到别的子类型。

另外一个优点是你可以把教师和学生对象都作为SchoolMember对象来使用,这在某些场合特别有用,比如统计学校成员的人数。

一个子类型在任何需要父类型的场合可以被替换成父类型,即对象可以被视作是父类的实例,这种现象被称为多态现象。(???与C++的区别???)

在 重用 父类的代码的时候,无需在不同的类中重复它。而如果我们使用独立的类的话,我们就不得不这么做了。

在上述的场合中,SchoolMember类被称为 基本类 或 超类 。而TeacherStudent类被称为 导出类 或 子类 。

#!/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'4030000)
s = Student(
'Swaroop'2275)

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函数的返回来取回对象。这个过程称为 取储存 。

--------------------------------------------------
第十三章
异常

SyntaxError语法错误

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语句 引发 异常。你还得指明错误/异常的名称和伴随异常 触发的 异常对象。你可以引发的错误或异常应该分别是一个ErrorException类的直接或间接导出类。

#!/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 = [234]
listtwo = [2*i for 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']"


 

 

posted on 2015-12-14 13:43  cquptzzq  阅读(1375)  评论(0编辑  收藏  举报

导航