目录导航
-
撤销(Ctrl+Z)
-
重做(Ctrl+Y)
-
清空
-
H
标题(Ctrl+1~6)
- 一级标题
- 二级标题
- 三级标题
- 四级标题
- 五级标题
- 六级标题
-
粗体(Ctrl+B)
-
斜体(Ctrl+I)
-
删除线
-
插入引用(Ctrl+Q)
-
无序列表(Ctrl+U)
-
有序列表(Ctrl+O)
-
表格
-
插入分割线
-
插入链接(Ctrl+L)
-
插入图片
- 添加图片链接
-
插入代码块
-
保存(Ctrl+S)
-
开启预览
-
开启目录导航
-
关闭同步滚动
-
全屏(按ESC还原)
* 编程是一种技能和工具,是理解计算机的有效途径,是一种新的思考方式。 #### 特点 * 语法简洁 * 类库丰富 * 跨平台 * 可拓展 * 开源 #### 历史 * 1990,诞生 * 2000,2.0发布 * 2008,3.0发布 * 2010,2的最后一个版本2.7 #### 数据类型 1. 整型:int 8 2. 浮点型:float 8.5 3. 字符:str "6" 4. 布尔型:bool true false ###### 数据类型操作 * type():查看数据类型 * 相同数据类型的数据才可以一起操作,例:"6"必须先转换成整型或浮点型才可以进行计算 #### 序列 ###### 定义 它的成员都是有序排列,并且可以通过下标偏移量访问它的成员。 ###### 范围 1. 字符串 "abc" 2. 列表 [4,6,7] 成员可以变更 3. 元组 ("234", "hi") 成员不可变更 ###### 序列基本操作 * 成员关系操作符:对象(in, not in)序列 * 连接操作符:序列 + 序列 * 重复操作符:序列 * 整数 * 切片操作符:序列[开始下标:结束下标] ``` # 下标从0开始,包含开头,不包含结尾 # 格式:序列[开始下标:结束下标] a = [4,6,7] a[1] # 结果为:6 a[1:2] # 结果为:[6] ``` ###### 列表基本操作 * 添加元素,添加到最后面 `list.append("x")` * 删除元素,删除最前面的一个元素 `list.remove("x")` #### 字典{} * 以键值对的形式出现,key会被进行hash运算存起来所以key不能重复, * 类型int float string tuple都可以进行hash运算可以作为key。 * 查询使用 get,如果查询的值不存在,我们也可以给一个默认值,比如 score.get(‘yase’,99)。 #### 集合{} * 集合(set)是一个**无序的不重复元素序列**。 * 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。 * `s = set(['a', 'b', 'c'])` #### 条件语句if ``` if 条件: 执行语句 elif 条件: 执行语句 else: 执行语句 ``` #### 循环语句while ``` while 条件: 执行语句 ``` #### 循环语句for ``` for 迭代变量 in 可迭代对象: 执行语句 ``` #### 映射类型:字典{} * 以键值对的形式出现 #### 文件操作 #### 错误≠异常 #### 迭代器 * 迭代是Python最强大的功能之一,是访问集合元素的一种方式。 * 迭代器是一个可以记住遍历的位置的对象。 * 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。 * 迭代器有两个基本的方法:iter() 和 next()。 * 字符串,列表或元组对象都可用于创建迭代器: #### 生成器 * 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。 * 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。 调用一个生成器函数,返回的是一个迭代器对象。 在 Python 中,使用了 yield 的函数被称为生成器(generator)。 #### a,b=b,a+b 和 a=b b=a+b 的区别 ``` a,b=0,1 a, b = b, a+b # 这种赋值,先计算等值 右边 就是 b=1 a+b=1 # 再赋值给a和b,那么 a=1, b=1 #然后就是依次这样 a = b # 此时 b=1, 那么a=1 b = a+b # 那么 b=2 ``` #### 匿名函数lambda * lambda 只是一个表达式,函数体比 def 简单很多。 * lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。 * lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。 * 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。 ###### 一个语法 * lambda的语法是唯一的 ``` lambda argument_list: expression ``` ###### 三个特性 1. **lambda函数是匿名的**:所谓匿名函数,通俗地说就是没有名字的函数。lambda函数没有名字。 2. **lambda函数有输入和输出**:输入是传入到参数列表argument_list的值,输出是根据表达式expression计算得到的值。 3. **lambda函数一般功能简单**:单行expression决定了lambda函数不可能完成复杂的逻辑,只能完成非常简单的功能。由于其实现的功能一目了然,甚至不需要专门的名字来说明。 ###### 四个用法 1. 将lambda函数赋值给一个变量,通过这个变量间接调用该lambda函数。 2. 将lambda函数赋值给其他函数,从而将其他函数用该lambda函数替换。 3. 将lambda函数作为其他函数的返回值,返回给调用者。 4. 将lambda函数作为参数传递给其他函数。 ###### 一个争议 * 关于lambda在Python社区是存在争议的 * 支持方认为使用lambda编写的代码更紧凑,更“pythonic”。 * 反对方认为,lambda函数能够支持的功能十分有限,其不支持多分支程序if...elif...else...和异常处理程序try ...except...。并且,lambda函数的功能被隐藏,对于编写代码之外的人员来说,理解lambda代码需要耗费一定的理解成本。他们认为,使用for循环等来替代lambda是一种更加直白的编码风格。 #### 内建函数 ###### filter() * filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。 * 该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。 ``` filter(function, iterable) # function -- 判断函数。 # iterable -- 可迭代对象。 # 返回一个迭代器对象 ``` ``` def is_odd(n): return n % 2 == 1 tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) newlist = list(tmplist) print(newlist) # 结果为:[1, 3, 5, 7, 9] ``` ###### map() * map() 会根据提供的函数对指定序列做映射。 * 第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。 ``` map(function, iterable, ...) # function -- 函数 # iterable -- 一个或多个序列 # Python 2.x 返回列表。 # Python 3.x 返回迭代器。 ``` ``` # 使用 lambda 匿名函数 map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # [1, 4, 9, 16, 25] # 提供了两个列表,对相同位置的列表数据进行相加 map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]) # [3, 7, 11, 15, 19] ``` ###### reduce() * reduce() 函数会对参数序列中元素进行累积。 * 函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。 * 在 Python3 中,reduce() 函数已经被从全局名字空间里移除了,它现在被放置在 functools 模块里,如果想要使用它,则需要通过引入 functools 模块来调用 reduce() 函数: ``` reduce(function, iterable[, initializer]) # function -- 函数,有两个参数 # iterable -- 可迭代对象 # initializer -- 可选,初始参数 ``` ``` from functools import reduce def add(x,y): return x + y print (reduce(add, range(1, 3)), 4) # 10 ``` ###### zip() * zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。 * 我们可以使用 list() 转换来输出列表。 * 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。 ``` zip([iterable, ...]) # iterabl -- 一个或多个迭代器; # python3返回的是对象,python2返回的是列表 ``` ``` z = zip([1,2,3],[4,5,6]) print(list(z)) # [(1, 4), (2, 5), (3, 6)] ``` #### 闭包 * 形成闭包的条件 1. 必须要有一个内嵌函数 2. 内嵌函数中要对自由变量的引用 3. 外部函数必须返回内嵌函数 ``` # a * x + b = y def line(a,b): def arg_x(x): return a * x + b return arg_x a_line = line(2,5) print(a_line(1)) # 7 ``` #### 装饰器 * 从字面上理解,就是装饰对象的器件。**可以在不修改原有代码的情况下,为被装饰的对象增加新的功能或者附加限制条件或者帮助输出。**装饰器有很多种,有函数的装饰器,也有类的装饰器。装饰器在很多语言中的名字也不尽相同,它体现的是设计模式中的装饰模式,强调的是开放封闭原则。装饰器的语法是将@装饰器名,放在被装饰对象上面。 ``` import time def timer(func): def wrapper(): start_time = time.time() func() stop_time = time.time() print(stop_time-start_time) return wrapper # 装饰器 @timer def i_can_sleep(): time.sleep(2) i_can_sleep() ``` #### 函数的基本概念 * 函数名:foo、outer、inner * 函数体:函数的整个代码结构 * 返回值:return后面的表达式 * 函数的内存地址:id(foo)、id(outer)等 * 函数名加括号:对函数进行调用,如foo()、outer(foo) * 函数名作为参数:outer(foo)中foo本身是一个函数,但作为参数传递给了outer函数 * 函数名加括号作为参数:先调用函数,再将它的返回值当做别的函数的参数,例如outer(foo()) * 返回函数名:return inner * 返回函数名加括号:return inner(),其实就是先执行inner()函数,再将其返回值作为别的函数的返回值。 #### 上下文管理器 * 用于规定某个对象的使用范围。一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存)。它的语法形式是with...as... * 上下文管理器协议:是指类需要实现 __ enter __ 和 __ exit __ 方法。 * 就跟迭代器有迭代器协议一样,迭代器协议需要实现 __ iter __ 和 __ next __ 方法。 * 上下文管理器,也就是支持上下文管理协议的对象,简单点讲就是,实现了 __ enter __ 和 __ exit __两个方法的类。这个类也叫做,上下文管理器的类。 ``` class Resource(): def __enter__(self): print('===connect to resource===') return self def __exit__(self, exc_type, exc_val, exc_tb): print('===close resource connection===') def operate(self): print('===in operation===') with Resource() as res: res.operate() 输出: ===connect to resource=== ===in operation=== ===close resource connection=== ``` #### 面向对象 * 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 * 方法:类中定义的函数。 * 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。 * 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。 * 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。 * 局部变量:定义在方法中的变量,只作用于当前实例的类。 * 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。 * 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。 * 实例化:创建一个类的实例,类的具体对象。 * 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。 * 两个下划线“__”开头的属性和方法是私有的 * \_\_init__ 是 构造方法 ###### 继承 * 子类继承父类的属性和方法,可以继承多个,当多个父类有相同方法时,默认从左向右取第一个父类的方法 ``` class Test: def prt(self): print(1) class Test2: def prt(self): print(2) class Test3(Test, Test2): def __init__(self): print(3) t = Test3() t.prt() # 3 1 ``` #### 多线程 * 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 * 每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。 * 指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。 ``` import threading import time from threading import current_thread def my_thread(arg1, arg2): print(current_thread().getName(), "start") print("%s %s" % (arg1, arg2)) time.sleep(2) print(current_thread().getName(), "stop") for i in range(1,6,1): t1 = threading.Thread(target=my_thread, args=(i, i+1)) t1.start() print(current_thread().getName(), "end") Thread-1 start # 1 2 # Thread-2 start # 2 3 # Thread-3 start # 3 4 # Thread-4 start # 4 5 # Thread-5 start # MainThread end # 5 6 # Thread-4 stop # Thread-3 stop # Thread-1 stop # Thread-2 stop # Thread-5 stop ``` #### 正则表达式 * 正则前面加上 r 表示规则不被转译 * re.compile() 设置匹配规则 * re.match()是从开头开始匹配,开头不符合直接返回None * re.search()是匹配整个字符串,有一个符合的就返回,没有一个符合的返回None * re.findall()是匹配整个字符串,返回所有符合的字符串组成的列表 * re.sub()是替换字符串 #### Python是如何进行内存管理的 1. 对象的引用计数机制 * Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。 引用计数增加的情况: * 一个对象分配一个新名称 * 将其放入一个容器中(如列表、元组或字典) 引用计数减少的情况: * 使用del语句对对象别名显示的销毁 * 引用超出作用域或被重新赋值 2. 垃圾回收 当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。 3. 内存池机制 * Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统: * Pymalloc机制:为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。 * 对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。 #### Numpy * NumPy 数组存储在一个均匀连续的内存块中,不需要对内存地址进行查找;而列表 list 的元素在系统内存中是分散存储的,需要对内存地址进行查找。 * 在内存访问模式中,缓存会直接把字节块从 RAM 加载到 CPU 寄存器中。因为数据连续的存储在内存中,NumPy 直接利用现代 CPU 的矢量化指令计算,加载寄存器中的多个连续浮点数。 * NumPy 中的矩阵计算可以采用多线程的方式,充分利用多核 CPU 计算资源,大大提升了计算效率。 * 提升内存和提高计算资源的利用率:避免采用隐式拷贝,而是采用就地操作的方式。
- 编程是一种技能和工具,是理解计算机的有效途径,是一种新的思考方式。
特点
- 语法简洁
- 类库丰富
- 跨平台
- 可拓展
- 开源
历史
- 1990,诞生
- 2000,2.0发布
- 2008,3.0发布
- 2010,2的最后一个版本2.7
数据类型
- 整型:int 8
- 浮点型:float 8.5
- 字符:str “6”
- 布尔型:bool true false
数据类型操作
- type():查看数据类型
- 相同数据类型的数据才可以一起操作,例:"6"必须先转换成整型或浮点型才可以进行计算
序列
定义
它的成员都是有序排列,并且可以通过下标偏移量访问它的成员。
范围
- 字符串 “abc”
- 列表 [4,6,7] 成员可以变更
- 元组 (“234”, “hi”) 成员不可变更
序列基本操作
- 成员关系操作符:对象(in, not in)序列
- 连接操作符:序列 + 序列
- 重复操作符:序列 * 整数
- 切片操作符:序列[开始下标:结束下标]
# 下标从0开始,包含开头,不包含结尾
# 格式:序列[开始下标:结束下标]
a = [4,6,7]
a[1] # 结果为:6
a[1:2] # 结果为:[6]
列表基本操作
- 添加元素,添加到最后面
list.append("x")
- 删除元素,删除最前面的一个元素
list.remove("x")
字典{}
- 以键值对的形式出现,key会被进行hash运算存起来所以key不能重复,
- 类型int float string tuple都可以进行hash运算可以作为key。
- 查询使用 get,如果查询的值不存在,我们也可以给一个默认值,比如 score.get(‘yase’,99)。
集合{}
- 集合(set)是一个无序的不重复元素序列。
- 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
s = set(['a', 'b', 'c'])
条件语句if
if 条件:
执行语句
elif 条件:
执行语句
else:
执行语句
循环语句while
while 条件:
执行语句
循环语句for
for 迭代变量 in 可迭代对象:
执行语句
映射类型:字典{}
- 以键值对的形式出现
文件操作
错误≠异常
迭代器
- 迭代是Python最强大的功能之一,是访问集合元素的一种方式。
- 迭代器是一个可以记住遍历的位置的对象。
- 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
- 迭代器有两个基本的方法:iter() 和 next()。
- 字符串,列表或元组对象都可用于创建迭代器:
生成器
- 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
- 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象。
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
a,b=b,a+b 和 a=b b=a+b 的区别
a,b=0,1
a, b = b, a+b
# 这种赋值,先计算等值 右边 就是 b=1 a+b=1
# 再赋值给a和b,那么 a=1, b=1
#然后就是依次这样
a = b
# 此时 b=1, 那么a=1
b = a+b
# 那么 b=2
匿名函数lambda
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
一个语法
- lambda的语法是唯一的
lambda argument_list: expression
三个特性
- lambda函数是匿名的:所谓匿名函数,通俗地说就是没有名字的函数。lambda函数没有名字。
- lambda函数有输入和输出:输入是传入到参数列表argument_list的值,输出是根据表达式expression计算得到的值。
- lambda函数一般功能简单:单行expression决定了lambda函数不可能完成复杂的逻辑,只能完成非常简单的功能。由于其实现的功能一目了然,甚至不需要专门的名字来说明。
四个用法
- 将lambda函数赋值给一个变量,通过这个变量间接调用该lambda函数。
- 将lambda函数赋值给其他函数,从而将其他函数用该lambda函数替换。
- 将lambda函数作为其他函数的返回值,返回给调用者。
- 将lambda函数作为参数传递给其他函数。
一个争议
- 关于lambda在Python社区是存在争议的
- 支持方认为使用lambda编写的代码更紧凑,更“pythonic”。
- 反对方认为,lambda函数能够支持的功能十分有限,其不支持多分支程序if…elif…else…和异常处理程序try …except…。并且,lambda函数的功能被隐藏,对于编写代码之外的人员来说,理解lambda代码需要耗费一定的理解成本。他们认为,使用for循环等来替代lambda是一种更加直白的编码风格。
内建函数
filter()
- filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。
- 该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
filter(function, iterable)
# function -- 判断函数。
# iterable -- 可迭代对象。
# 返回一个迭代器对象
def is_odd(n):
return n % 2 == 1
tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
newlist = list(tmplist)
print(newlist)
# 结果为:[1, 3, 5, 7, 9]
map()
- map() 会根据提供的函数对指定序列做映射。
- 第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
map(function, iterable, ...)
# function -- 函数
# iterable -- 一个或多个序列
# Python 2.x 返回列表。
# Python 3.x 返回迭代器。
# 使用 lambda 匿名函数
map(lambda x: x ** 2, [1, 2, 3, 4, 5])
# [1, 4, 9, 16, 25]
# 提供了两个列表,对相同位置的列表数据进行相加
map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
# [3, 7, 11, 15, 19]
reduce()
- reduce() 函数会对参数序列中元素进行累积。
- 函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。
- 在 Python3 中,reduce() 函数已经被从全局名字空间里移除了,它现在被放置在 functools 模块里,如果想要使用它,则需要通过引入 functools 模块来调用 reduce() 函数:
reduce(function, iterable[, initializer])
# function -- 函数,有两个参数
# iterable -- 可迭代对象
# initializer -- 可选,初始参数
from functools import reduce
def add(x,y):
return x + y
print (reduce(add, range(1, 3)), 4)
# 10
zip()
- zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。
- 我们可以使用 list() 转换来输出列表。
- 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
zip([iterable, ...])
# iterabl -- 一个或多个迭代器;
# python3返回的是对象,python2返回的是列表
z = zip([1,2,3],[4,5,6])
print(list(z))
# [(1, 4), (2, 5), (3, 6)]
闭包
- 形成闭包的条件
- 必须要有一个内嵌函数
- 内嵌函数中要对自由变量的引用
- 外部函数必须返回内嵌函数
# a * x + b = y
def line(a,b):
def arg_x(x):
return a * x + b
return arg_x
a_line = line(2,5)
print(a_line(1))
# 7
装饰器
- 从字面上理解,就是装饰对象的器件。**可以在不修改原有代码的情况下,为被装饰的对象增加新的功能或者附加限制条件或者帮助输出。**装饰器有很多种,有函数的装饰器,也有类的装饰器。装饰器在很多语言中的名字也不尽相同,它体现的是设计模式中的装饰模式,强调的是开放封闭原则。装饰器的语法是将@装饰器名,放在被装饰对象上面。
import time
def timer(func):
def wrapper():
start_time = time.time()
func()
stop_time = time.time()
print(stop_time-start_time)
return wrapper
# 装饰器
@timer
def i_can_sleep():
time.sleep(2)
i_can_sleep()
函数的基本概念
- 函数名:foo、outer、inner
- 函数体:函数的整个代码结构
- 返回值:return后面的表达式
- 函数的内存地址:id(foo)、id(outer)等
- 函数名加括号:对函数进行调用,如foo()、outer(foo)
- 函数名作为参数:outer(foo)中foo本身是一个函数,但作为参数传递给了outer函数
- 函数名加括号作为参数:先调用函数,再将它的返回值当做别的函数的参数,例如outer(foo())
- 返回函数名:return inner
- 返回函数名加括号:return inner(),其实就是先执行inner()函数,再将其返回值作为别的函数的返回值。
上下文管理器
- 用于规定某个对象的使用范围。一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存)。它的语法形式是with…as…
- 上下文管理器协议:是指类需要实现 __ enter __ 和 __ exit __ 方法。
- 就跟迭代器有迭代器协议一样,迭代器协议需要实现 __ iter __ 和 __ next __ 方法。
- 上下文管理器,也就是支持上下文管理协议的对象,简单点讲就是,实现了 __ enter __ 和 __ exit __两个方法的类。这个类也叫做,上下文管理器的类。
class Resource():
def __enter__(self):
print('===connect to resource===')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('===close resource connection===')
def operate(self):
print('===in operation===')
with Resource() as res:
res.operate()
输出:
===connect to resource===
===in operation===
===close resource connection===
面向对象
-
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
-
方法:类中定义的函数。
-
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
-
数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
-
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
-
局部变量:定义在方法中的变量,只作用于当前实例的类。
-
实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
-
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
-
实例化:创建一个类的实例,类的具体对象。
-
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
-
两个下划线“__”开头的属性和方法是私有的
-
__init__ 是 构造方法
继承
- 子类继承父类的属性和方法,可以继承多个,当多个父类有相同方法时,默认从左向右取第一个父类的方法
class Test:
def prt(self):
print(1)
class Test2:
def prt(self):
print(2)
class Test3(Test, Test2):
def __init__(self):
print(3)
t = Test3()
t.prt()
# 3 1
多线程
- 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
- 每个线程都有他自己的一组CPU寄存器,称为线程的上下文,该上下文反映了线程上次运行该线程的CPU寄存器的状态。
- 指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器,线程总是在进程得到上下文中运行的,这些地址都用于标志拥有线程的进程地址空间中的内存。
import threading
import time
from threading import current_thread
def my_thread(arg1, arg2):
print(current_thread().getName(), "start")
print("%s %s" % (arg1, arg2))
time.sleep(2)
print(current_thread().getName(), "stop")
for i in range(1,6,1):
t1 = threading.Thread(target=my_thread, args=(i, i+1))
t1.start()
print(current_thread().getName(), "end")
Thread-1 start
# 1 2
# Thread-2 start
# 2 3
# Thread-3 start
# 3 4
# Thread-4 start
# 4 5
# Thread-5 start
# MainThread end
# 5 6
# Thread-4 stop
# Thread-3 stop
# Thread-1 stop
# Thread-2 stop
# Thread-5 stop
正则表达式
- 正则前面加上 r 表示规则不被转译
- re.compile() 设置匹配规则
- re.match()是从开头开始匹配,开头不符合直接返回None
- re.search()是匹配整个字符串,有一个符合的就返回,没有一个符合的返回None
- re.findall()是匹配整个字符串,返回所有符合的字符串组成的列表
- re.sub()是替换字符串
Python是如何进行内存管理的
- 对象的引用计数机制
- Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。
引用计数增加的情况: - 一个对象分配一个新名称
- 将其放入一个容器中(如列表、元组或字典)
引用计数减少的情况: - 使用del语句对对象别名显示的销毁
- 引用超出作用域或被重新赋值
-
垃圾回收
当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。 -
内存池机制
- Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统:
- Pymalloc机制:为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。
- 对于Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
Numpy
- NumPy 数组存储在一个均匀连续的内存块中,不需要对内存地址进行查找;而列表 list 的元素在系统内存中是分散存储的,需要对内存地址进行查找。
- 在内存访问模式中,缓存会直接把字节块从 RAM 加载到 CPU 寄存器中。因为数据连续的存储在内存中,NumPy 直接利用现代 CPU 的矢量化指令计算,加载寄存器中的多个连续浮点数。
- NumPy 中的矩阵计算可以采用多线程的方式,充分利用多核 CPU 计算资源,大大提升了计算效率。
- 提升内存和提高计算资源的利用率:避免采用隐式拷贝,而是采用就地操作的方式。
评论
请
登录后发表观点