《python学习手册》读书笔记


我学习python是从《python简明教程》开始的,后来自己又买了《python基础教程(第2版)》。 简明教程虽然打印出来只有薄薄一本,但是里面从python介绍,到安装,再到基本语法都有概括,可以让读者对python有一个大概的了解,不像某些编程语言书籍那样厚厚的,让人晦涩难懂,我相信读过之后都会对python的浅显易懂印象深刻,并深深爱上他。 基础教程这本书对python有了更详细的介绍,增加网络编程、图形界面、数据库等内容,同时介绍了程序的打包和发布的一些方法,最后还有10个项目的开发方法。这本书既夯实了一些基础,又让读者对python 的使用提升了技能。 最近我在图书馆借了《python学习手册(第3版)》,希望能把一些遗漏的基础知识补上并且对python的原理进一步了解。下面是我的一些笔记:

Python如何运行程序?

  1. 编译成字节码(因为没有编译成二进制代码,所以不如C/C++那样快)
  2. 发送到python虚拟机上执行

a = 3这个表达式干了什么?

  1. 创建一个对象来代表值3
  2. 创建一个变量a
  3. 将变量a与对象3相连

Python的回收机制是怎样的?
通过对象中的计数器来记录引用次数,每与一个变量连接+1,当次数减为0时自动回收

字符与ASCII码可以转换:

ord(‘s’)
115
Chr(115)
‘s’

列表是:

  1. 任意对象的有序集合
  2. 通过偏移读取
  3. 可变长度、异构、任意嵌套,甚至可以排序

关于比较:
== 测试相等性
is 是否同一个对象

python对缩进的要求:
python没有用 { } 来表示同一个代码块,所以看起来很整洁很舒服,但这造成对缩进的要求非常严格,曾经以为必须是4格或者tab键。但事实是编译器不在乎怎么缩进,也不在乎缩进多少,只在乎缩进相同的距离。

Print 与 sys.stdout 的关系:
print x 等价于

import sys
sys.stdout.write(str(x) + ‘n’)

可以使用print语句将内容写入文件,只需:

import sys
sys.stdout = open(‘test.txt’, ‘a’)
content = ‘Hello!’
print content

因为sys.stdout重设为已打开的文件对象,所以程序任何地方的print都会将print的内容写入到test.txt文件的末尾。如需切换回来,只需: Sys.stdout.close()

所有的变量名,包括作用域的定义在内,都是在python赋值的时候生成的。

LEGB原则:四个作用域(按顺序自顶向下)

  1. 内置:在内置变量名模块中预定义的变量名
  2. 全局(模块):在模块文件顶层赋值的变量名,或是在def中声明为global的变量名
  3. 上层函数的本地作用域:任何以及所有上层函数(def或lambda)作用域的变量名
  4. 本地(函数):def或lambda内,通过赋值但并没有声明为global的变量名

例:
X = 99 ##在模块顶层注册,所以是全局变量
def fun(Y): ##func也是全局变量
Z = X + Y ## X Y是本地变量名
return Z

关于lambda:
创建一个之后能调用的函数,但它返回了一个函数而不是将这个函数赋值给一个变量名
语法:lambda + 一个或多个参数 : 一个表达式
Lambda argument1, argument2 … :expression
与def的区别:

  1. lambda是一个表达式而不是语句
  2. 是单个表达式而不是一个代码块

例:

f = lambda x, y, z: x + y + z
f(2, 3, 4)
# output: 9

生成器:
Yield语句会将函数挂起并向调用者返回一个值,同时保存状态信息,以便能从挂起的地方恢复。这允许它不断产生一系列的值而不是一次计算所有的值。

import如何工作? import并不像C中的#include那样,当第一次执行import指定文件时,会执行

  1. 找到模块文件
  2. 编译成字节码(若需要)
  3. 执行模块的代码来创建其定义的对象

具体一点: import module ##(.py是刻意省略的)
搜索路径有:程序的主目录、python path目录、标准链接库目录、.pth文件的内容
所以可能导入:

  1. module.py或字节码文件 module.pyc
  2. 目录module
  3. 编译扩展模块
  4. 用C编写的编译如内置模块
  5. Zip文件组件(导入时会自动解压)

运行:
import操作的最后步骤是执行模块的字节码,文件中所有语句会依次执行,所以模块中顶层的print语句会显示其输出内容
注意:import只发生一次,也就是说初始化也只发生依次,之后的导入只会使用已加载的模块对象

from … import …语句:
from会把变量名复制到另一个作用域,所以可以直接使用模块中的变量名或方法名,而不需要指明模块名

reload: 与import 和from不同的是:

  1. reload是内置函数,而不是语句
  2. 传给reload的是已经存在的模块对象而不是变量名

reload会重读模块文件的源代码,重新执行器顶层语句
为什么用reload?
因为reload允许修改程序的一些部分而无须停止整个程序。

关于__name__这个内置属性: 每个模块都有一个名为__name__的内置属性,若文件以顶层程序文件执行时,在启动时,__name__会自动设置为”main”;如果该文件是被导入的,__name__会设为客户端所了解的模块名。这就是为什么使用if __name__ == “__main__”:,因为这样可以避免文件被作为模块导入使用。

属性继承搜索顺序: 先搜索该类,然后往上搜索超类。所以集成后,函数名重复会覆盖父类中的方法。

__init__构造器方法:

class person():
    def \_\_inti\_\_(self, name):
    self.data = name
    def display():
        print self.data

这样在创建对象时就可以把name传入,例:liam = person(“liam”)