python学习笔记

python 笔记

独立环境

graph TB
pyenv-->wrappervirtualenv_lazy
wrappervirtualenv_lazy-->mkvirtualenv
mkvirtualenv-->workon

I/O multiplexing

graph TB
DefaultSelector--生成事件注册-->register
fileobj--参数-->register
events--参数-->register
data--参数-->register
register--instance-->SelectorKey
SelectorKey--event is ready-->select
select --> event_list("[(key, events),(SelectorKey instance, bitmask of events ready ),...]")
event_list-->SelectorKey
event_list-->mask
SelectorKey-->fileobj
SelectorKey-->fd
SelectorKey-->events
SelectorKey-->data

设计模型

1. 装饰器(decorator)模式

(俄罗斯套娃封装)

1
2
3
@装饰器二
@装饰器一
核心对象
  1. 创建一个装饰函数,内部定义一个wrapper新函数执行一些操作,将被装饰函数作为参数传入装饰函数,返回新函数
  2. 行为类似多重继承.
  3. 当在装饰器与继承之间选择时,只需要根据一些条件对对象进行动态修改时使用装饰器.
    1. 日志装饰器,传递一些参数动态记录日志
  4. 作用:
    1. 增强核心对象的能力
    2. 让核心对象支持多种可选行为
    3. 编写判断执行不同的装饰器

2. 观察者模式

状态监测,事件处理

1
核心对象->update()->观察者们->各自处理自已的任务

1564143774413

3. 策略模式

每个策略类都包含同名方法,接收相同参数.

1
2
核心对象->策略1
核心对象->策略2

4.状态模式

状态类的目的是实现状态转换,需要一个上下文类提供转换接口和指针指向状态类,状态类对前面的调用者是隐藏的.

1
2
3
4
5
6
Context -> state -> [state1, state2, state3] -> Parser
OpenTag
||
FirstTag -> ChildNode <=> Text
||
CloseTag

策略模式用于运行时选择一种算法,如一张图片根据不同的情况处理成不同的状态

状态模式用于允许在不同状态之间进行动态切换,如解析XML文件,context上下文切换

5.单件模式

只有一个实例的对象类.

模块级实例变量能够模仿单件实例

6.模板模式

7.适配模式(adapter)

接口适配转换

8.外观模式(facade)

为复杂的组件提供典型用途的简单接口,如requests为urllib,编写发送邮件的类为smtplib,samplib等

9.享元模式

专为节省内存而设计的,如果有成百上千的相同对象,将相同特性整合进一个享元可极大减少内存消耗.

10.命令模式

11.抽象工厂模式

12.组合模式

简单的组件构成复杂的树状结构

迭代器iterator&递归器

  1. 迭代器
    1. 字符串(有时需要将字符串视为原子的.否则有时有可能导致无穷递归.)
    2. 每次只取一个对象,不会对内存造成巨大开销.
  2. 递归器

表达式 & 语句

  1. 表达式有返回值
    1. yield是表达式,所以调用生成器需要next()来执行表达式
    2. send是传递值给yield表达式

python 运算符

Python逻辑运算符

Python语言支持逻辑运算符,以下假设变量 a 为 10, b为 20:

运算符 逻辑表达式 描述 实例
and x and y 布尔”与” - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 (a and b) 返回 20。
or x or y 布尔”或” - 如果 x 是非 0,它返回 x 的值,否则它返回 y 的计算值。 (a or b) 返回 10。
not not x 布尔”非” - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 not(a and b) 返回 False

数学运算

1
2
3
4
5
6
7
8
9
+ plus
- minus
/ slash
* asterisk
% percent
< less-than
> greater-than
<= less-than-equal
>= greater-than-equal

print

1
print "If I add %d, %r, and %d I get %d." % (my_age, my_height, my_weight, my_age + my_height + my_weight)

标识符 %s, %r, %d

byte & string

Unicode
字符串和二进制数据流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# bytes object
b = b"example"

# str object
s = "example"

# str to bytes
bytes(s, encoding = "utf8")

# bytes to str
str(b, encoding = "utf-8")

# an alternative method
# str to bytes
str.encode(s)

# bytes to str
bytes.decode(b)

编码就是把一个字符用一个二进制来表示。
字符串类str里有一个encode()方法,它是从字符串向比特流的编码过程。而bytes类型恰好有个decode()方法,它是从比特流向字符串解码的过程。
ASCII码,一种8位即1个字节的编码规范,它可以涵盖整个英语系的编码需要。
python 中编码print后会以ascii编码方式显示,所以中文会显示16进制,英文会直接显示ascii后的原文.

世界标准:

ASCII(en:1byte,8bits) =>

unicode(en:2bytes,16bits; cn:3bytes,24bits) =>

utf-8(en:1byte,8bits; cn:3bytes,24bits)

中国标准

GBK 2bytes, 16bits

输入

raw_input()

Parameters

argument 命令行参数
Parameters

文件读写

close – Closes the file. Like File->Save.. in your editor.
read – Reads the contents of the file. You can assign the result to a variable.
readline – Reads just one line of a text file.
truncate – Empties the file. Watch out if you care about the file.
write(‘stuff’) – Writes “stuff” to the file.

函数

  • 匿名函数

    lambda x: x * 8

  • 回调函数

    作为参数传入中间函数的函数

    回调实际上有两种:阻塞式回调和延迟式回调。两者的区别在于:阻塞式回调里,回调函数的调用一定发生在起始函数返回之前;而延迟式回调里,回调函数的调用有可能是在起始函数返回之后。

  • 中间函数

    需要传入回调函数的函数

  • 起始函数

    调用中间函数的函数

  • 装饰函数

    ​ 代码风格

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def logging_tool(func):
    def wrapper(*arg, **kwargs):
    logging.info('%s is running...' % func.__name__)
    # 把today当作参数传递进来,执行func()就相当于执行today()
    func()
    return wrapper

    @logging_tool
    def today():
    print('2018-05-25')

    today()

多进程,多线程

What is a process? A process is just an instance of an executing program.
sbla(socket, bind, listen, accept)
process -> UNIX fork()

进程>线程>协程

Python对协程的支持是通过generator实现的。

子程序顺序栈式调用,不可乱序

协程(Coroutine)中断式调用,可乱序

子程序,或者称为函数,在所有语言中都是层级调用(栈式调用),比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。

子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。

Python中的协程大概经历了如下三个阶段:

  1. 最初的生成器变形yield/send
  2. 引入@asyncio.coroutine和yield from
  3. 在最近的Python3.5版本中引入async/await关键字

同步的异步实现

借助 Python 的 generator 功能TwistedTornado 纷纷提供了这样的功能。

生成器(generator)(协程)(yield,需要多次调用:执行先中断,返回变量,再执行.)

函数是顺序执行,生成器也是顺序计算的.

协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点类似CPU的中断。

  1. 列表推导式 -> []

    1. 直接打印
  2. 生成器推导式 -> ()

    1. next(generator)激活,最后一个返回StopIteration error
    2. generator保存的是算法,调用才开始计算
    3. 可迭代对象
    4. 生成器并没有将所有值放入内存中,而是实时地生成这些值,并且不会保存上一次迭代生成的值,因而,在迭代一个比较大的数据的时候,使用迭代器更好
    5. yield 的作用就是返回迭代器
    6. python直到遇到关键字yield之后,中断代码执行,返回yield变量值
    7. send 函数就是给yield语句赋值
      1. 先调用,返回原值(send并不会改变yield的返回值)
      2. 发送send,修改变量,并返回next值
      3. 因为当send方法的参数为None时,它与next方法完全等价(不规范,慎用)
    8. close可以关闭生成器
  3. 生成器使用场景

    1. 项目中如何使用yield,使用的思路就是,中断代码执行,在yield之前打开一个资源,然后在yield之后关闭这个资源,这样可以很好地保证每次只有一个资源被打开,同时执行完成之后资源会被关闭
    2. 第二个思路,就是节约内存,不要一下子加载所有的资源
    3. IO密集型

条件判断

if 语句的判断条件可以用>(大于)、<(小于)、==(等于)、>=(大于等于)、<=(小于等于)来表示其关系。

True & False

针对Python中的True和False的定义,在不同版本的Python中是这样定义的:

  • Python 2:None, 0, 和空字符串都被算作 False,其他的均为 True
  • Python 3:None,0,空字符串,空列表,空字典都算是False,所有其他值都是True

面向对象

propterty() and @property:对属性做限制/检查操作

  1. 类属性

  2. 实例属性

1
2
3
4
5
6
7
8
class Person():
person = 'tianfei' #这是类变量
def __init__(self,name ,age):
self.name = name #这是实例变量
self.age = age #这是实例变量
self.sex = '男' #这是实例变量
#a = 456 #不能写这里,会出错
place = ['地球','中国'] #这是类变量
  1. 编写代码首要考虑它的可读性(DRY不要让自己重复)

    1. 继承(超类里也可定义子类才有的方法,使得自己成为通用类)
    2. 组合(大部分继承关系都可以建模替代为组合关系,反之大部分组合都不能建模为继承)
      1. 关联

1564058294189

  1. 如果只对数据操作->使用python数据结构

  2. 如果只关注行为不存储数据->使用函数

如果同时包含数据和行为 ->使用对象->代码更易读而不关心长短,对象之间的继承,关联,组合.

  • 随着程序的进一步扩展,需要把一组相关的变量传递到不同的函数中,这是一个将变量函数组合成类的好场景.(数据与行为的分离)

    • 存储数据(名词)

      • 数据对象CRUD操作行为使用property

        • property()函数是python的builtin函数,它是一个粘合剂,将对象“.”操作符和set、get、del方法粘合起来,并且,让下划线的私有变量可以在类外访问。

        • 1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          class Student(object):

          @property
          def score(self):
          return self._score

          @score.setter
          def score(self, value):
          if not isinstance(value, int):
          raise ValueError('score must be an integer!')
          if value < 0 or value > 100:
          raise ValueError('score must between 0 ~ 100!')
          self._score = value
- 参数也是另一种对象类型(自身就是文档)
  • 数据行为操作(动词)

    • 为了看起来像函数一样更易用,可以在init构造函数中接收参数而不是在方法中.
  • 管理对象(有点类似之前自己使用main实现的函数,保证步骤顺序)

    python不像java语言,类私有变量可以直接访问,所以变量可以直接访问,无需访问方法.

使用property优雅的处理对象属性:可以直接访问name->property构造函数->调用方法,看起来跟直接访问属性一样.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Color:
def __init__(self, rgb_value, name):
self.rgb_value = rgb_value
self._name = name
def _set_name(self, name):
if not name:
raise Exception("Invalid Name")
def _get_name(self):
return self._name
name = property(_get_name, _set_name)
# or 另一种风格
@property
# foo.getter 对于长消耗的操作,可以只取一次然后缓存起来.
def foo(self):
return self._foo
@foo.setter
def foo(self, value):
self._foo = value

其它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
from __future__ import absolute_import
*** 忽略当前包下的模块,导入系统模块.
相对导入:在不指明 package 名的情况下导入自己这个 package 的模块,比如一个 package 下有 a.py 和 b.py 两个文件,在 a.py 里 from . import b 即是相对导入 b.py。

绝对导入:指明顶层 package 名。比如 import a,Python 会在 sys.path 里寻找所有名为 a 的顶层模块。

from __future__ import absolute_import: 在 3.0 以前的旧版本中启用相对导入等特性所必须的 future 语句。
如果你在main.py中写import string,那么在Python 2.4或之前, Python会先查找当前目录下有没有string.py, 若找到了,则引入该模块,然后你在main.py中可以直接用string了。如果你是真的想用同目录下的string.py那就好,但是如果你是想用系统自带的标准string.py呢?那其实没有什么好的简洁的方式可以忽略掉同目录的string.py而引入系统自带的标准string.py。这时候你就需要from __future__ import absolute_import了。
---------------------


相同缩进
:开始缩进,短语句可以直接跟在:后面
;可以连接多个操作语句
#注释
'''大段注释'''
"""大段注释"""
基本输入:raw_input()
基本输出:print()
#-*- coding:utf-8 -*- 解决中文乱码
print(var.decode('utf-8').encode('cp936'))
交互命令下可以当计算器使用。
import math基本的数学模块
数据类型是程序的基础。程序设计的本质就是对数据进行处理。
使用python数据结构基本不用考虑自己重新定义数据结构。
数字,python中可以使用任意大的数字。
基本类型:(整数,长整数,浮点数,复数),使用前无需声明其类型。
运算符:**,*,/,%,+,-,|,^,&,<<,>>按优先级下降
>>> 2.30-1.30
0.9999999999999998由于浮点数精度问题。
>>> 5^3 101^011=110
6
>>> 11|5 1011|0101=1111
15
>>> 4<<2 100<<2=10000 等同于4*2**2
16
字符串:'',"",""" """,''' '''
转义符:\n,\t,\r,\\,\',\"
原始字符串:R或r开头
str操作方法:https://docs.python.org/3.5/library/stdtypes.html#string-methods
字符串索引,分片 []
字符串格式化:%c单字符,%d十进制数,%o八进制数,%s字符串,%x十六进制数,字母小写,%X十六进制数,字母大写
%c%s%d % ('a','talen',5)
>>> print( "%c%s%d" % ('a','talen',5))
atalen5
字符串与数字的相互转换
int(str),str(int)
>>> int("10") +4
14
列表list[]
字典dict{key:value}
file

if,else
for
while

函数:def name(args):
return



python
对象
元素
数据结构
自定义类
容器
序列 (迭代,索引,分片,加,乘,成员资格,最大,最小,长度)
列表
元组
字符串
Unicode对象
buffer对象
xrange对象
映射
字典(python惟一内置映射类型)
集合
语句


import 模块
函数(参数),函数可嵌套函数
内置函数
外置导入,from 模块名 import 函数,可以使用变量引用函数,效果等同函数操作。
类型对象

模块名.函数

多态:操作的意义取决于操作对象的类型

第4章:python的核心对象类型
数字、列表、字典、元组、
第5章:数字
对象是python中最基本的概念,python编程的基础是对象。
python完整数字类型工具:
整数与浮点数
复数
固定精度的十进制数
有理分数
集合
布尔类型
无穷的整数精度
各种数字内置函数和模块
内置表达式操作符: + - * / >> ** &等。
表达式是处理数字的最基本工具。
混合操作符表达式的优先级P120表5.2.越向后优先级越高。
使用()分组子表达式改变优先级。
混合数字类型操作会将简单类型升级为复杂类型再计算。复杂度:整型<浮点<复数
内置数学函数: pow, abs, round, int, hex, bin等
公用模块: random, math等

变量:
变量在它第一次赋值时创建。
变量在表达式中使用将被替换为它们的值。
变量在表达式中使用前必须赋值。
变量像对象一样不需要一开始进行声明。
数字的显示格式:
  repr代码交互式
  str用户友好式
比较:一般比较与连续的长比较
对数字启作用,比较结果是一个布尔类型








python基础教程
第1章 基础知识
列表,字符串,字典是python中最重要的三种数据类型。
第2章 列表(可变)与元组(不可变)
数据结构:是通过方式对元素的集合
容器数据结构:包含其它对象的任意对象。主要有序列(列表,元组等)与映射(字典等),集合。
序列中的每个元素都有一个编号,映射每个元素都有一个键。
python中最基本的数据结构是序列(内置6种,重点包括元组与列表,其它有字符串,Unicode字符串,buffer对象,xrange对象),元素序号是索引。
操作一组数值时,使用序列。
序列中可以包含序列。
序列操作:
索引
>>> getting = 'hello'
>>> getting[1]
'e'
>>> getting[-1]
'o'
>>> 'hello'[1]
'e'

分片
冒号分割,2个索引作为边界,每1个索引在分片内,第2个在分片外。
使用捷径
更大的步长,使用负数做为步长时,必须让开始点大于结束点。

相同类型的序列才可以连接。

None内置代表空 *
成员资格
in 返回True False
长度,最大元素,最小元素。
迭代(interation): 依次对序列中的元素重复执行操作。
列表 [a,b,n...]
list()
元素赋值,元素删除,分片赋值,列表方法。
列表方法:
方法是函数,但只对特定对象进行操作,如序列,字典等。
对象.方法(参数)
append 入𣏾
count
extend
index
insert
pop 惟一一个修改列表并返回值的方法。出𣏾
remove 移出但不返回值,跟pop不同。
reverse 反序
sort
高级排序 cmp,key,reverse
元组:不可变序列 (a,n...)
tuple
第3章 使用字符串
基本字符串操作
适用所有标准序列操作,如上一章
字符串如元组一样不可修改
字符串操作符%
format % values values一般是元组,字典可格式多个值。如果使用列表,只能格式为一个值。
%.3f %s
模板字符串
from string import Template
变量.substitute()
字段宽度和精度
转换说明符可以包括字段宽度与精度。
可以使用*号作为字体宽度或精度,这个值可以从后面的元组中读取。
标表
0,-,+,' ',放置在宽度或精度字段。 对齐,0填充。
字符串方法:
 find 返回最左端的索引 字符串.find('内容',起点,终点)
 split join相反的操作。分割,合并字符串
  join添加的队列必须是字符串。
 lower
 replace
 strip 去除两侧空格。
 translate 只替换单个字符。
第4章 字典:当索引不好用时
4.1字典的使用
{k键:v值}
4.2 创建与使用字典
  4.2.1 dict函数
  4.2.2 基本字典操作
   键类型:更多类型
   自动添加:列表不能不使用append的方法外自动建立。
   成员资格:字典比列表检查成员资格更高效。
第5章 条件、循环、其它语句
5.1 print,import
print 逗号输出多个表达式
+链接字符没有空格输出,逗号有空格输出。
from module import function as name
5.2 赋值魔法
序列解包
链式赋值
增量赋值 +=,*=,/=,%=
5.3 语句块:缩排的乐趣
布尔变量:假:false None 0 "" () [] {}
布尔函数:bool
5.4 条件
if :
elif:
else:
使用==判断两个对象是否相等,使用is判断两者是否等同。
多重if可以用布尔判断代替。
命名空间:作用域:in scope ,调用使用scope()函数

第6章 抽象abstraction
抽象结构:组织可读性程序,细节在其它地方定义。
函数:
调用()中的参数或值,执行一系列操作,返回一个值。
创建函数是组织程序的关键。
def 函数名(参数)
操作
return result
记录函数:文档字符串,在函数开头写,使用函数.__doc__访问。
形参,实参
def 形参
调用 实参
函数内的局部作用域
使用关键字参数忘记顺序
使用多个参数 *是生成元组,**生成字典
python 命令空间,作用域,变量是不可见的字典 vars()
local variable
globals 变量名可以在函数作用域内定义全局变量。
递归:引用自身,调用自身的意思。================
二元搜索
第7章 更加抽象,创建自己的数据类型自定义类。
面向对象的编程。
核心概念。
object.method()对象.方法()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
baseexcept(SystemExit , KeyboardInterrupt , and GeneratorExit (these three derive directly from BaseException instead).
exception
arithmeticerror(the superclass of Over flowError , ZeroDivisionError , and FloatingPointError ,
and a subclass of Exception .)
buffererror

类:
动: 方法
静: 数据
带访问控制的数据属性(property)(getter,setter,deleter,text)(自动调用一些自定义动作)


第三节:
没有self的类变量会被所有类实例共享,作用域是类;self变量作用域是类实例,只有类实例可以使用.

新式父类调用
super().__init__(name, email)
旧式父类调用
super(subclass_name).__init__(name, email)


多态:调用不同的子类实现不同的行为.
different behaviors happen depending on which subclass is being used, without having to explicitly know what the subclass actually is.
python的动态特性让其它编程中的多态变得不太重要.
class AudioFile:
def __init__(self, filename):
if not filename.endswith(self.ext): # 父类并没有定义ext变量,但可以访问子类中的变量
raise Exception("Invalid file format")
self.filename = filename

class MP3File(AudioFile):
ext = "mp3"
def play(self):
print("playing {} as mp3".format(self.filename))

类静态方法(staticmethod)与类关联,被所有类实例共享


异常:
BaseException
SystemExist
KeyboardInterrupt
Exception
Most other Exceptions
except:或except BaseException:将捕捉所有异常
except Exception:只捕捉Exception类

对于一些使用if else的语句,也可以使用异常来做程序流控,会更简洁.



property声明
坚持原创技术分享,您的支持将鼓励我继续创作!