目录
本文参考自《Beginning Python: from novice to professional》,中文版为《Python基础教程(第三版)》。
1 快速上手:基础知识
-
from __future__import xxx
:从python2.1开始,当一个新的语言特性首次出现在发行版中时,如果该新特性与旧版本的python不兼容,则该新特性默认会被禁用。要想启用这个新特性,必须使用该语句进行导入。 -
/
:除法 ;//
:整除,向下圆整;%
:求余;**
:乘方 -
round 圆整到最接近的整数,并在两个整数一样近时圆整到偶数。
-
nan 具有特殊含义,指的是“非数值”(not a number)。
-
#!/usr/bin/env python
:无需显式地使用Python解释器$ hello.py
-
str() 的输出追求可读性,输出格式要便于理解,适合用于输出内容到用户终端。
repr() 的输出追求明确性,除了对象内容,还需要展示出对象的数据类型信息,适合开发和调试阶段使用。
>>> print(repr("Hello,\nworld!")) 'Hello,\nworld!' >>> print(str("Hello,\nworld!")) Hello, world
-
要表示很长的字符串(跨越多行的字符串),可使用三引号(而不是普通引号)。
-
原始字符串用前缀 r 表示,不能以单个反斜杠结尾。
>>> print(r'Let\'s go!') Let\'s go! >>> print(r'C:\Program Files\foo\bar' '\\') C:\Program Files\foo\bar\
2 列表和元组
- 元组语法很简单,只要将一些值用逗号分隔,就能自动创建一个元组。
- 只包含一个值的元组,在它后面加上逗号。
3 字符串
- 字符串是不可变的
4 字典
- 在字典中,键的排列顺序是不固定的,因此打印字典时,每次的顺序都可能不同。
5 条件、循环及其他
-
print
# 自定义分隔符,默认的是空格 >>> print("I", "wish", "to", "register", "a", "complaint", sep="_") I_wish_to_register_a_complaint # 自定义结束字符串,以替换默认的换行符。例如,如果将结束字符串指定为空字符串,以后就可继续打印到当前行。 print('Hello,', end='') print('world!')
-
赋值魔法
-
序列解包/赋值魔法:
# 星号运算符( * )来收集多余的值,这样无需确保值和变量的个数相同 >>> name = "Albus Percival Wulfric Brian Dumbledore" >>> first, *middle, last = name.split() >>> middle ['Percival', 'Wulfric', 'Brian'] # 带星号的变量最终包含的总是一个列表。
-
链式赋值:将多个变量关联到同一个值。
x = y = somefunction()
-
增强赋值:
x += 1
-
-
布尔值:
False None 0 "" () [] {}
为假,其他为真; True 和 False 不过是0和1的别名 -
支持链式比较:可同时使用多个比较运算符,如 0 < age < 100
-
== 用来检查两个对象是否相等,而 is 用来检查两个对象是否相同(是同一个对象)。
-
添加 assert 语句充当检查点
>>> age = -1 >>> assert 0 < age < 100, 'The age must be realistic'
-
并行迭代:zip
for name, age in zip(names, ages): print(name, 'is', age, 'years old')
-
迭代时获取索引:enumerate
-
判断循环是否是提前结束:
from math import sqrt for n in range(99, 81, -1): root = sqrt(n) if root == int(root): print(n) break else: print("Didn't find it!")
无论是在 for 循环还是 while 循环中,都可使用 continue 、 break 和 else 子句。
-
列表推导:使用多个 for 部分时,也可添加 if 子句。
>>> girls = ['alice', 'bernice', 'clarice'] >>> boys = ['chris', 'arnold', 'bob'] >>> [b+'+'+g for b in boys for g in girls if b[0] == g[0]] ['chris+clarice', 'arnold+alice', 'bob+bernice']
-
字典推导:for 前面有两个用冒号分隔的表达式。这两个表达式分别为键及其对应的值。
>>> squares = {i:"{} squared is {}".format(i, i**2) for i in range(10)} >>> squares[8] '8 squared is 64'
-
exec 执行一系列Python语句,而 eval 计算用字符串表示
的Python表达式的值,并返回结果( exec 什么都不返回,因为它本身是条语句)。 -
添加第二个参数——字典,用作代码字符串的命名空间,避免污染原来的命名空间。
>>> from math import sqrt >>> scope = {} >>> exec('sqrt = 1', scope) >>> sqrt(4) 2.0 >>> scope['sqrt'] 1
6 抽象
-
放在函数开头的字符串称为文档字符串(docstring),将作为函数的一部分存储起来。
square.__doc__
help(square)
-
前面使用的参数都是位置参数,使用名称指定的参数称为关键字参数,主要优点是有助于澄清各个参数的作用。
hello_3(name='Gumby')
-
收集参数:
def print_params_2(title, *params): print(title) print(params) def in_the_middle(x, *y, z): print(x, y, z) >>> in_the_middle(1, 2, 3, 4, 5, z=7)
星号意味着收集余下的位置参数。带星号的参数也可放在其他位置(而不是最后),此时使用名称来指定后续参数。
收集关键字参数,可使用两个星号。这样得到的是一个字典而不是元组。
>>> def print_params_3(**params): ... print(params) ... >>> print_params_3(x=1, y=2, z=3) {'z': 3, 'x': 1, 'y': 2}
-
分配参数
def add(x, y): return x + y params = (1, 2) >>> add(*params)
通过使用运算符 ** ,可将字典中的值分配给关键字参数。
-
可使用函数 globals 来访问全局变量。这个函数类似于 vars ,返回一个包含全局变量的字典。( locals 返回一个包含局部变量的字典。)
-
重新关联全局变量,
global x
-
递归:基线条件(针对最小的问题):满足这种条件时函数将直接返回一个值。递归条件:包含一个或多个调用,这些调用旨在解决问题的一部分。
-
函数式编程
>>> list(map(str, range(10))) # 与[str(i) for i in range(10)]等价 ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] lambda x, y: x+y # 匿名函数
7 再谈抽象
- 多态(polymorphism) 方法 鸭子类型
- 多态让你无需知道对象所属的类(对象的类型)就能调用其方法,而封装让你无需知道对象的构造就能使用它。
- 封装 属性
- 多重继承,是一个功能强大的工具。然而,除非万不得已,否则应避免使用多重继承
- 抽象类是不能(至少是不应该)实例化的类,其职责是定义子类应实现的一组抽象方法。
8 异常
-
在没有出现异常时执行一个代码块,不管 try 子句中发生什么异常,都将执行 finally 子句。
try: 1 / 0 except NameError: print("Unknown variable") else: print("That went well!") finally: print("Cleaning up.")
-
闭眼就跳,直接去做,有问题再处理,而不是预先做大量的检查。
9 魔法方法、特性和迭代器
-
构造函数(constructor)
-
super(SongBird, self)
;super().__init__()
-
基本的序列和映射协议
__len__(self) :
__getitem__(self, key) :
__setitem__(self, key, value):
__delitem__(self, key) :
-
size = property(get_size, set_size)
调用函数 property 并将存取方法作为参数(获取方法在前,
设置方法在后)创建了一个特性,然后将名称 size 关联到这个特性。 -
迭代器
class TestIterator: value = 0 def __next__(self): self.value += 1 if self.value > 10: raise StopIteration return self.value def __iter__(self): return self
当你调用方法
__next__
时,迭代器应返回其下一个值。如果迭代器没有可供返回的值,应引发 StopIteration 异常。next(it) 与
it.__next__()
等效。 -
生成器:包含 yield 语句的函数都被称为生成器
每次使用 yield 生成一个值后,函数都将冻结,即在此停
止执行,等待被重新唤醒。被重新唤醒后,函数将从停止的地方开始继续执行。 -
生成器推导:不立即执行循环,而是返回一个生成器,让你能够逐步执行计算。
>>> g = ((i + 2) ** 2 for i in range(2, 27)) >>> next(g) 16 sum(i ** 2 for i in range(10))
-
递归式生成器
-
生成器由两个单独的部分组成:生成器的函数和生成器的迭代器。生成器的函数是由 def 语句定义的,其中包含 yield 。生成器的迭代器是这个函数返回的结果。用不太准确的话
说,这两个实体通常被视为一个,通称为生成器。
10 开箱即用
-
导入模块多次和导入一次的效果相同
>>> import sys >>> sys.path.append('C:/python')
-
if __name__ == '__main__': test()
-
模块存储在扩展名为.py的文件中,而包则是一个目录。
-
探索模块
[n for n in dir(copy) if not n.startswith('_')]
列出所有的函数、类、变量等__all__ = ["Error", "copy", "deepcopy"]
旨在定义模块的公有接口,如果不设置__all__
,则会在以 import * 方式导入时,导入所有不以下划线打头的全局名称。
-
常用模块
- 在较新的版本中,集合是由内置类 set 实现
- 堆(heap),它是一种优先队列。优先队列让你能够以任意顺序添加对象,并随时(可能是在两次添加对象之间)找出(并删除)最小的元素。
- 正则表达式
- 正则表达式是可匹配文本片段的模式:在文本中查找模式,将特定的模式替换为计算得到的值,以及将文本分割成片段。
- 句点与除换行符外的任何字符都匹配,因此被称为通配符(wildcard)。
- 例如 ‘[a-zA-Z0-9]’ 与大写字母、小写字母和数字都匹配。请注意,字符集只能匹配一个字符。
- 例如
'[^abc]'
与除a、b和c外的其他任何字符都匹配。
11 文件
with open("somefile.txt") as somefile:
do_something(somefile)
13 数据库支持
- Python DB API
- 模块 sqlite3
14 网络编程
- 模块 socket
15 Python和Web
- flask
16 测试基础
- 测试一点点,再编写一点点代码
17 扩展Python
- 鱼和熊掌兼得
- 使用Python开发原型
- 对程序进行性能分析以找出瓶颈
- 使用C(或者C++、C#、Java、Fortran等)扩展重写瓶颈部分。
18 程序打包
- pyinstaller
19 趣味编程
- 原型设计:尝试性实现
- 配置:
- 提取代码中的符号常量
- configparser
- 日志:模块 logging