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

编辑器:windows,linux
不要用notepad,缩进糟糕
--------------
5.18 缩进
同一层次的语句必须有相同的缩进。每一组这样的语句称为一个块。
1 i = 5
2   print ( 'Value is ' , i) # Error! Notice a single space at the start
of the line行首有空格
3 print ( 'I repeat, the value is ' , i)
当你运行的时候,会得到下面的出错信息:
1 File "whitespace.py", line 4
2 print('Value is ', i) # Error! Notice a single space at the start
of the line
3 ^
4 IndentationError: unexpected indent
-------------
如何缩进
不要混合使用制表符和空格来缩进,因为这在跨越不同的平台的时候,无法正常工作。我强烈建
议你在每个缩进层次使用单个制表符或两个或四个空格。
----------
给静态语言程序员的注释:
Python 总是使用缩进来代表代码块,不再使用括号。
--------------------------------------------------------------------------------
第七章     控制流
7.2 if 语句
#!/usr/bin/python
2 # Filename: if.py
3
4 number = 23
5 guess = int ( input ( 'Enter an integer : ' ))
6
7 if guess == number:
8 print ( 'Congratulations, you guessed it.' ) # New block starts
here
9 print ( '(but you do not win any prizes!)' ) # New block ends here
10 elif guess < number:
11 print ( 'No, it is a little higher than that' ) # Another block
12 # You can do whatever you want in a block ...
13 else :
14 print ( 'No, it is a little lower than that' )
15 # you must have guess > number to reach here
16 print ( 'Done' )
17 # This last statement is always executed, after the if statement is
executed
-----------
注意:input()与raw_input()的区别
网上:前者可以计算数值,后者表示字符串
--------------
最简单的有效 if 语句是:
1 if True :
2 print ( 'Yes, it is true' )
---------------------------------
while 语句
# !/usr/bin/python
2 # Filename while.py
3
4 number = 23
5 running = True
6
7 while running:
8 guess= int ( input ( "Enter an integer:" ))
9
10 if guess == number:
11 print ( "Congratulation, you guessed it." )
12 running= False #this causes the while loop to stop
13 elif guess < number:
14 print ( "No, it is a little higher." )
15 else :
16 print ( "No, it is a little lower." )
17 else :
18 print ( "the while loop is over." )
19 # Do anything else you want to do here
20
21 print ( "done" )
输出:
1 $ python while.py
2 Enter an integer : 50
3 No, it is a little lower than that.
4 Enter an integer : 22
5 No, it is a little higher than that.
6 Enter an integer : 23
7 Congratulations, you guessed it.
8 The while loop is over.
9 Done
-------------------
7.4 for 循环
#!/usr/bin/python
2 # Filename: for.py
3
4 for i in range ( 1 , 5 ):
5 print (i)
6 else :
7 print ( 'The for loop is over' )
输出:
1 $ python for.py
2 1
3 2
4 3
5 4
6 The 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
4 while True :
5 s = ( input ( 'Enter something : ' ))
6 if s == 'quit' :
7 break
8 print ( 'Length of the string is' , len(s))
9 print ( 'Done' )
输出:
1 $ python break.py
2 Enter something : Programming is fun
3 Length of the string is 18
4 Enter something : When the work is done
5 Length of the string is 21
6 Enter something : if you wanna make your work also fun:
7 Length of the string is 37
8 Enter something : use Python!
9 Length of the string is 12
10 Enter something : quit
11 Done
-------------------------
7.7 continue 语句
continue 语句被用来告诉 Python 跳过当前循环块中的剩余语句,然后继续进行下
一轮循环。
-----------------------------------------------------------------------------
第八章函数
函数用关键字 def 来定义。 def 关键字后跟一个函数的标识符名称,然后跟一对
圆括号。圆括号之中可以包括一些变量名,该行以冒号结尾。接下来是一块语句,它
们是函数体。
def sayHello():
5 print ( 'Hello World!' ) # block belonging to the function
6 # End of function
7 sayHello() # call the function
8 sayHello() # call the function again
----------------
8.2 函数的参数
def printMax(a,b):
5       if a > b:
6       print (a, 'is maximum' )
7       elif a == 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
4 x = 50
5
6 def func():
7 global x
8
9 print ( 'x is' ,x)
10 x = 2
11 print ( 'Changed global x to' ,x)
12
13 func()
14 print ( '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
4 def func_outer():
5 x = 2
6 print ( 'x is' ,x)
7
8 def func_inner():
9 nonlocal x
10 x = 5
11
12 func_inner()
13 print ( 'Changed local x to' ,x)
14
15 func_outer()
-------------
nonlocal的理解:局部内的全局语句。
在外函数中定义了一个局部变量,当在外函数内部再建立一个内函数,并想让内函数内的变量在整个外函数内是全局的,
就可以用nonlocal
-------------------------------
8.6 默认参数值
在函 数定义的形参名后加上赋值运算符( = )和默认值,从而给形参指定默认参数值。
注意,默认参数值应该是一个参数。更加准确的说,默认参数值应该是不可变的
4 def say(message, times = 1):
5 print (message * times)
6
7 say( 'Hello' )
8 say( 'World' , 5)
输出:
1 $ python func_default.py
2 Hello
3 WorldWorldWorldWorldWorld
-------------------
重要的:
只有在形参表末尾的那些参数可以有默认参数值,即你不能在声明函数形参的时候,先声明有默
认值的形参而后声明没有默认值的形参。这是因为赋给形参的值是根据位置而赋值的。例如, def
func(a, b=5) 是有效的,但是 def func (a=5, b) 是无效的。
------------------------
8.7 关键参数
如果某个函数有许多参数,而你只想指定其中的一部分,可以通过命 名来为这些参数赋值 —— 这被称作关键参数 —— 我们使用名字(关键字)而不是位置(我们前面所一直使用的方法)来给函数指定实参。
4 def func(a, b=5, c=10):
5 print ( 'a is' , a, 'and b is' , b, 'and c is' , c)
6
7 func(3, 7)
8 func(25, c=24)
9 func(c=50, a=100)
-------------
8.8 VarArgs 参数
定义一个能获取任意个数参数的函数,这可通过使用 * 号来实现。
4 def total(initial=5, *numbers, **keywords):
5 count = initial
6 for number in numbers:
7 count += number
8 for key in keywords:
9 count += keywords[key]
10 return count
11
12 print (total(10, 1, 2, 3, vegetables=50, fruits=100))
----------------
8.10 return 语句
4 def maximum(x, y):
5 if x > y:
6 return x
7 else :
8 return y
9
10 print (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  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__':
5 print ( 'This program is being run by itself' )
6 else :
7 print ( 'I am being imported from another module' )
输出:
1 $ python using_name.py
2 This program is being run by itself
3 $ python
4 >>> import using_name
5 I 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
2 Hi, this is mymodule speaking.
3 Version 0.1
 
第二个版本:
3
4 from mymodule import sayhi, __version__
5
6 sayhi()
7 print ( 'Version' , __version__)
如果已经在导入 mymodule 的模块中申明了一个 __version__ 的名字,这就
会有冲突。这也是有可能的,因为从实际情况来看,每个模块会用这个名字来申明它
的版本。因此,推荐选择使用 import 语句,虽然会导致程序稍微有点冗长。
你也可以这样使用:
1 from mymodule import *
这会导入像 sayhi 这样公用的名字,但不会导入 __version__ ,因为它是以双下划
线开始的。
--------------
9.6 dir 函数
使用内建的 dir 函数来列出模块定义的标识符。标识符有函数、类和变量。
当你为 dir() 提供一个模块名的时候,它返回模块定义的名称列表。如果不提供
参数,它返回当前模块中定义的名称列表。
1 $ python
2 >>> import sys # get list of attributes, in this case, for the sys
module
3 >>> dir(sys)
4 [ '__displayhook__' , '__doc__' , '__excepthook__' , '__name__' ,
5 '__package__' , '__s
6 tderr__' , '__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 >>> del a # 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
4 class Person:
5 pass # An empty block
6
7 p = Person()
8 print (p)
输出:
1 $ python simplestclass.py
2 <__main__.Person object at 0x019F85F0>
我们使用 class 语句后跟类名,创建了一个新的类。这后面跟着一个缩进的语句
块形成类体。在这个例子中,我们使用了一个空白块,它由 pass 语句表示。
接下来,我们使用类名后跟一对圆括号来创建一个对象 / 实例。
class Person:
5 def sayHi( self ):
6 print ( 'Hello, how are you?' )
7
8 p = Person()
9 p.sayHi()
10 # This short example can also be written as Person().sayHi()
输出:
1 $ python method.py
2 Hello, how are you?
12.5 __init__ 方法
__init__ 方法在类的一个对象被建立时,马上运行。这个方法可以用来对你的对
象做一些你希望的初始化。注意,这个名称的开始和结尾都是双下划线。
1 #!/usr/bin/python
2 # Filename: class_init.py
3
4 class Person:
5 def __init__( self , name):
6 self .name = name
7 def sayHi( self ):
8 print ( 'Hello, my name is' , self .name)
9
10 p = Person( 'Swaroop' )
11 p.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
def howMany():
     ……………………
如何工作:
(???)
  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类被称为 基本类 或 超类 。而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']"


 

 

转载于:https://www.cnblogs.com/cquptzzq/p/5045025.html

你可能感兴趣的:(python读书笔记-《A Byte of Python》中文第三版后半部分)