关于Python无需多介绍,作为一个编程渣,非常后悔没有早接触到这个简洁明了的预言而是直接碰到了C/C++。
Python编程的书也看过好几本了,之所以看这一本是想把基本的语法再简单整理一下。笔记里大部分都是对我有意义的内容,包括了语法介绍和实例代码。

2.7.1 列出模块中的函数

导入模块后,可使用函数dir(m)列出模块的所有函数。

2.7.2 打印文档字符串

另一个实用技巧是打印函数的文档字符串。

>>> print(math.tanh.__doc__)

2.8.3 将浮点数转换为整数

Python采用了另一种圆整策略:将小数部分为.5的数字圆整到最接近的偶数

2.11 变量如何引用值

  • 对于x = expr这样的Python赋值语句,可以这样解读:让x指向表达式expr的值。

  • 一般而言,Python跟踪所有的值,并自动删除不再有变量指向的值。这称为垃圾收集,因此Python程序员很少需要为删除值操心。

2.11.1 赋值时不复制

赋值语句并不会复制指向的值,而只是标记和重新标记既有值。

2.11.2 数字和字符串是不可变的

在Python中,数字和字符串的一个重要特征是不可变,即不能以任何方式修改它们。在看起来是修改数字或字符串的情况下,Python实际上是在创建修改版本的拷贝

2.12 多重赋值

语句a, b = b, a的含义是,同时给变量a和b赋值。

3.2 编译源代码

Python由3个主要部分组成:运行语句的解释器、将.py文件转换为.pyc文件的编译器以及运行.pyc文件的虚拟机。

3.3.1 跟踪程序

  • 要获悉字符串包含哪些函数,可在IDLE的交互式命令行输入dir(”)。
  • 因为经常需要删除不需要的空白,所以我们常常像下面这样调用函数input:
name = input('Enter age: ').strip()

3.4 在屏幕上打印字符串

  • 修改字符串分隔符很容易,可以像下面这样做:
>>> print('jack', 'ate', 'no', 'fat',→ sep = '.')
  • 要在同一行打印所有文本,可将第一行的结束字符指定为空字符串(只支持Python3):
# jack2.py
print('jack ate ', end = '')
print('no fat')

4.1.8 短路求值

p or q
如果p为False,结果为q,否则结果为pp and q
如果p为False,结果为p,否则结果为q

4.6 跳出循环和语句块

一般而言,明智的选择是,除非break语句让代码更简单或更清晰,否则不要使用它。

5.2 定义函数

  • Python还有一个很有用的工具——doctest,可用于自动运行文档字符串中的Python示例代码。
  • 除返回值外,函数以其他任何方式所做的修改都被称为副作用(side effect);打印到屏幕、写入文件和下载网页都属于副作用。

5.3 变量的作用域

要访问全局变量,必须使用关键字global

5.5.1 按引用传递

  • 向函数传递参数时,Python采用按引用传递的方式。
  • Python不支持按值传递。

5.5.3 默认值

函数可根据需要使用任意数量的默认参数,但带默认值的参数不能位于没有默认值的参数前面。

5.5.4 关键字参数

调用使用关键字参数的函数时,以param= value的方式传递数据。

5.6.2 名称空间

在较大的程序中,明智的做法是不使用from … import *语句。

6.2 字符

  • 所有字符都有对应的字符编码,你可以使用函数ord来获悉
  • 给定字符编码,可使用函数chr来获悉对应的字符

6.3 字符串切片

要对字符串执行切片操作,可指定两个索引:要提取的第一个字符的索引;要提取的最后一个字符的索引加1。

6.4.1 测试函数

s.isalnum()       #s只包含字母或数字
s.isidentifier()  #s是合法的标识符
s.isnumeric()     #s只包含数字

6.4.2 搜索函数

函数find引发异常ValueError,第9章将更详细地介绍异常。如果没有找到指定的子串,函数index将返回-1。

6.4.3 改变大小写的函数

s.capitalize()    #将s[0]改为大写
s.swapcase()      #将小写字母改为大写,并将大写字母改为小写

6.4.5 剥除函数

s.strip(ch)     #从s开头和末尾删除所有包含在字符串ch中的字符

6.4.6 拆分函数

s.split(t)      #以t为分隔符,将s划分成一系列子串,并返回一个由这些子串组成的列表
s.splitlines()  #返回一个由s中的各行组成的列表

6.5.1 简单的正则表达式

  • 正则表达式’cats?’描述了两个字符串:’cat’和’cats’。
  • ‘a*’描述的是由零或更多个’a’组成的字符串。正则表达式’a+’与’a*’相同,但排除了空字符串”。

6.5.2 使用正则表达式匹配字符串

re.match('(ha)+!+', s)!= None

7.1 type命令

通过使用type,可获悉Python对象的准确类型。

7.2 序列

Python有3种内置的序列类型:字符串、元组和列表。

7.3 元组

空元组用()表示,但只包含一个元素的元素(单元素元组)采用不同寻常的表示法(x,)

7.4 列表

在处理列表的程序中查找错误时,通常必须明白列表元素指向其值,而不包含它们。

7.5 列表函数

s.pop(i)         #删除并返回s中索引为i的元素
  • 函数extend类似于append,但在末尾添加一个序列

7.6 列表排序

函数sort总是按升序排列元素——从最小到最大。

7.7 列表解析

如何使用列表解析来创建一个由1~10的平方组成的列表:

>>> [n * n for n in range(1, 11)]

7.7.1 列表解析示例

cap_names = [n.capitalize() for n in names]

7.7.2 使用列表解析进行筛选

result = [n for n in nums if n > 0]
' '.join(c for c in s if c.lower() not in 'aeiou')

这样,传递给join的表达式将是一个生成器表达式。

7.8 字典

Python字典利用了一个巧妙的编程诀窍——散列。从本质上说,字典中的每个键都被转换为一个数字——散列值,这是使用专门设计的散列函数完成的。字典的值存储在一个底层列表中,并将其散列值用作索引。访问值时,把提供的键转换为散列值,再跳到列表的相应位置。计算散列的细节很复杂,所幸的是,Python为我们处理了这一切。

7.8.2 字典函数

d.get(key)      #返回与key相关联的值
d.pop(key)     #删除键key并返回与之相关联的值
d.popitem()   #返回字典d中的某个键-值对
  • d[key]返回与key相关联的值。调用d.get(key)可完成同样的任务。
  • 如果你预先不确定某个键是否包含在字典中,可使用key in d进行检查。

7.9 集合

集合最常见的用途可能是用于删除序列中的重复元素

8.2 格式字符串

'My {pet} has {prob}'.format(pet = 'dog', prob='fleas')
  • 在格式字符串中,用大括号括起的内容都将被替换,这称为命名替换(named replacement)。
  • 你可以使用大括号来指定格式设置参数,如下所示:
'num = {x:.{d}f}'.format (x=1/81, d=3)'num = 0.012'
  • 如果只想创建一些格式简单的字符串,字符串插入可能是最佳的选择;而格式字符串更适合庞大而复杂的设置任务,如创建网页或格式邮件。

8.3.1 文件夹

  • Windows路径名使用反斜杠(\)来分隔路径中的名称,并以盘符(这里是C:)打头。
  • 在Mac和Linux系统中,使用斜杠(/)来分隔名称,且不以盘符打头。

8.4 检查文件和文件夹

os.getcwd()              #返回当前工作目录的名称
os.listdir(p)              #返回一个字符串列表,其中包含路径p指定的文件夹中所有文件和文件夹的名称
os.chdir(p)               #将当前工作目录设置为路径
pos.path.isfile(p)      #当路径p指定的是一个文件的名称时,返回True,否则返回Falseos.path.isdir(p) #当路径p指定的是一个文件夹的名称时,返回True,否则返回Falseos.stat(fname)  #返回有关fname的信息,如大小(单位为字节)和最后一次修改时间
return [fname for fname in os.listdir(path)
if os.path.isfile(fname) if fname.endswith('.py')]  #优雅

8.5.2 将整个文本文件作为一个字符串进行读取

print(open(fname, 'r').read())

8.5.3 写入文本文件

如果你不想覆盖story.txt,应先检查它是否存在:

#write.py
import osdef make_story2():
if os.path.isfile('story.txt'): print('story.txt already exists')
else: f = open('story.txt', 'w')
f.write('Mary had a little lamb,\n') f.write('and then she had some more.\n')

8.5.5 将字符串插入到文件开头

要将文本插入到文件开头,最简单的方式可能如下:将文件读取到一个字符串中,将新文本插入到该字符串,再将这个字符串写入原来的文件,如下所示:

def insert_title(title, fname = 'story.txt'):  f = open(fname, 'r+')
temp = f.read() temp = title + '\n\n' + temp
f.seek(0) \# 让文件指针指向文件开头 
f.write(temp)

8.6 处理二进制文件

def is_gif(fname):
f = open(fname, 'br') first4 = tuple(f.read(4))
return first4 == (0x47, 0x49, 0x46, 0x38)

这个函数检查fname是不是GIF图像文件,方法是检查其前4个字节是不是 (0x47, 0x49, 0x46, 0x38)(所有GIF图像文件都以这4个字节打头)。
- 你可使用pickle.dump将数据结构存储到磁盘,以后再使用pickle.load从磁盘获取数据结构。
- pickle不能用于读写特殊格式的二进制文件,如GIF文件。对于这样的文件,必须逐字节处理。

8.7 读取网页

一种常见的任务是让程序自动读取网页,而使用模块urllib可轻松地完成这种任务:

>>> import urllib.request
>>>> resp = urllib.request.urlopen('http://www.python')>>> html = resp.read()
  • 另一个绝妙的模块是webbrowser,它让你能够以编程方式在浏览器中显示网页。

9.2.1 try/except块

if语句根据布尔表达式的结果决定如何做,而try/except块根据是否出现了异常决定如何做。

9.2.2 捕获多种异常

如果要分别处理不同的异常,可使用多个except子句

9.2.3 捕获所有异常

如果你在except子句中没有指定异常,它将捕获所有异常:

def convert_to_int3(s, base): try:
return int(s, base) except:
return 'error'

9.3 清理操作

  • 通常将关闭文件的语句放在finally块中,这样文件肯定会被关闭,即便发生了IOError异常。
  • 为确保不再需要的文件被尽早关闭,可使用with语句:
num = 1with open(fname, 'r') as f:
for line in f: print('%04d %s' % (num, line), end = '')
num = num + 1

这个代码片段的屏幕输出与前一个代码片段相同,但使用with语句时,将在for循环结束后立即执行文件对象清理操作(即关闭文件),避免了不再需要的f处于打开状态。

10.2 显示对象

  • 特殊方法__str__用于生成对象的字符串表示
def __str__(self):
return "Person('%s', %s)" % → (self.name, self.age)
  • 你还可定义特殊方法__repr__,它返回对象的“官方”(official)表示。
  • 在大多数类中,方法__repr__都与方法__str__相同
  • 如果你定义了方法__repr__,但没有定义方法__str__,则对对象调用str()时,将执行__repr__

10.4 设置函数和获取函数

可编写特殊的设置函数(setter)和获取函数(getter),对存取值的方式进行控制。首先,添加一个设置函数,它仅在提供的值合理时才修改age:

def set_age(self, age): if 0 < age <= 150:
self.age = age

10.4.1 特性装饰器

  • 获取函数返回变量的值,我们将使用@property装饰器来指出这一点:
@propertydef 
age(self):
""" Returns this person's age. """
return self._age

这个age方法除必不可少的self外不接受任何参数。我们在它前面加上了@property,指出这是一个获取函数。这个方法的名称将被用于设置变量。

@property
def age(self): return self._age

@age.setter
def age(self, age): if 0 < age <= 150:
self._age = age

10.4.2 私有变量

  • 为降低变量self._age被直接修改的可能性,一种方式是将其重命名为self.__age,即在变量名开头包含两个下划线。两个下划线表明age是私有变量,不应在Person类外直接访问它。要直接访问self.__age,需要在前面加上_Person,如下所示:
>>> p._Person__age = -44
  • 编写大型程序时,一条实用的经验规则是,首先将所有对象变量都设置为私有的(即以两个下划线打头),再在有充分理由的情况下将其改为公有的。这可避免无意间修改对象内部变量导致的错误。

11.2 保留想要的字母

def normalize2(s):
"""Convert s to normalized string. """
return ''.join(c for c in s.lower() → if c in keep)

11.4 找出出现次数较多的单词

lst = []
for k in d: pair = (d[k], k)
lst.append(pair)#
# [(2, 'a'), (1, 'ago'),# (1, 'galaxy'), (1, 'time'),
# (2, 'far'), ...]lst.sort()
## [(1, 'ago'), (1, 'away'),
# (1, 'galaxy'), (1, 'in'),# (1, 'long'), ...]
lst.reverse()#
# [(2, 'far'), (2, 'a'),# (1, 'time'), (1, 'long'),
# (1, 'in'), ...]

附录A 深受欢迎的Python包

  • PIL:Python图像处理库
  • Tkinter:Python GUI
  • Django:交互式网站
  • Bottle:交互式网站
  • Pygame:2D动画
  • SciPy:科学计算
  • Twisted:网络编程

更多推荐

《Python编程入门(第3版)》学习笔记