Python基础知识学习记录专栏
Python
Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。
由于Python是一种解释型语言,所以开发过程中没有了编译这个环节,Python是交互式语言,可以直接执行python代码,Python支持面向对象的风格或代码封装在对象的编程技术。
Python的内存管理
Python的内存管理主要是从三个方面进行的
- 对象的引用计数机制
- 垃圾回收机制
- 内存池机制
对象的引用计数机制
Python内部使用引用计数,来保持跟踪内存中的对象,所有对象都有引用计数,当一个对象的引用计数为0的时候,这个对象将会被垃圾回收机制进行回收。
引用计数增加的主要场景:
- 对象被创建时: a = “ABC”
- 引用创建时: b = a
- 被当做参数传递给函数的时候:foo(a)
- 作为容器对象(list,元组,字典)的一个元素时: lis = [1, a, ‘33’]
引用计数减少的主要场景:
- 一个本地引用离开了他的作用域的时候:foo(a)函数结束时,a指向的对象引用减少1
- 引用的对象被显示的销毁时: del a
- 对象的引用被赋值给其他对象时: a = 7
- 对象从一个容器对象(list,元组,字典) 中移除的时候:lis.remove(a)
- 容器对象本身被销毁 del lis 或者容器对象本身离开了作用域
python的垃圾回收
垃圾回收是Python和Java等语言进行内存管理的一种方式,用来清除无用的垃圾对象。在C语言以及C++中需要开发人员去手动进行内存的维护,但是在Python和Java中有自动的内存管理机制,不在需要动态的释放内存,这种机制就是垃圾回收。垃圾回收机制还有一个循环垃圾回收器,确保释放循环引用对象(a引用b,b引用a导致其计数永远不为0)
内存池机制
Python提供了对内存的垃圾收集机制,但是Python并不是将不用的内存返回给操作系统,而是将不用的内存放到了内存池中。
对于Python对象,整数、浮点数、List都有独立的私有内存池,对象间不共享他们的内存池。如果分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
Pymalloc机制
为了加速Python的执行效率,Python引入了一个内存池机制,用于管理小块内存的申请和释放,Python中所有小于256个字节的对象都使用pymalloc实现的分配器。
malloc机制
当需要使用的内存块大于256字节的时候,就会直接使用系统的malloc,每次分配一块大小为256K的大块内存,经由内存池等级的内存的回收还是会回到内存池,并不会调用C的free释放掉,以便下次使用。
Python的匿名函数
lambda表达式通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。 首要用途就是指短小的回调函数。
# 匿名函数的格式
lambda [arguments]:expression
# 例子
# lambda函数的声明
a = lambda x,y:x+y
# lambda函数的使用
a(3,11)
Python的数据类型
Python中有6个标准的数据类型:Number(数字),String(字符串),List(列表),Tuple(元组),Set(集合),Dictionary(字典)
Python中的6个标准的数据类型中又分成了可变数据和不可变数据:
可变数据:List(列表),Dictionary(字典),Set(集合)
不可变数据:Number(数字),String(字符串),Tuple(元组)
Number
python3支持int,float,bool,complex(复数)
python3中的整数类型全部为长整型
Python的数字类型用于存储数值
数据类型是不允许改变的,如果改变数字类型的值,将重新分配内存空间
数值运算
加 +
减 -
乘 *
除 / //
取余 %
乘方 **
数值的除法中/ 计算结果为浮点数,//计算结果为整数
数学函数
使用的时候需要引入 math包 import math
函数 | 返回值-描述 |
---|---|
abs(x) | 返回数字的绝对值 |
ceil(x) | 返回数字的上入整数 |
exp(x) | 返回x次幂 |
fabs(x) | 返回数字的绝对值 |
floor(x) | 返回数字的下舍整数 |
log(x) | 返回数值的log |
log10(x) | 返回以10位基数的x的对数 |
max(x1, x2, … ) | 返回给定参数的最大值 |
min(x1, x2, … ) | 返回给定参数的最小值 |
modf(x) | 返回x的整数部分与小数部分,整数部分以浮点数表示 |
pow(x, y) | 计算次幂 |
round(x, [n]) | 返回浮点数的四舍五入值,n代表小数后的位数 |
sqrt(x) | 返回数字x的平方根 |
随机数函数
随机数可以用于数学,游戏,安全等领域,还经常被嵌入到算法中,用来提高算法效率, 并且提高程序的安全性。
使用时需要引入random包, import random
函数 | 描述 |
---|---|
choice(sqe) | 从序列中的元素中随机挑选一个元素 |
randrange([start,]stop,[step] | 从指定的范围内,按照指定的步长递增的集合中随机获得一个随机数,技术默认值为1 |
random() | 随机生成下一个实数,在[0,1)之间 |
seed([x]) | 改变随机数生成器的种子seed |
shuffle(lst) | 将序列的所有元素随机排序 |
uniform(x, y) | 随机生成下一个实数,在[x,y]范围内 |
String
Python中的字符串用单引号或者双引号括起来,使用反斜杠 \ 转义特殊字符。
注意:
- 反斜杠可以用来转义,使用r来修饰可以让反斜杠不发生转义
- 字符串可以使用运算符 + 进行拼接,使用运算符 * 进行重复
- 字符串索引从左以0开始,从右以-1开始
Python的常用字符串内建函数:
方法 | 描述 |
---|---|
capitalize() | 将字符串的第一字符转换为大写 |
center(width, fillchar) | 返回一个指定的宽度width居中的字符串,fillchar为填充的字符串,默认为空格 |
count(str, beg=0,end=len(string)) | 返回str在string里面出现的次数,如果beg或end指定免责返回指定范围内str出现的次数 |
encode(encoding=‘UTF-8’, errors=‘strict’) | 以encoding指定的编码格式编码字符串,如果出错默认报一个ValueError的一场,除非errors指定的是ignor或者replace |
endwith(suffix, beg=0,end=len(string)) | 检查字符串是否以obj结束,如果beg或end指定,则检查指定范围内是否以obj结束,如果是,返回True,否则返回False |
expandtabs(tabsize=8) | 把字符串string中的tab符号转为空格,tab符号默认的空格数是8 |
find(str, beg=0, end=len(string)) | 检测str是否包含在字符串中,如果指定范围beg和end,则检查是否包含在指定范围内,如果包含则返回开始的索引值,否则返回-1 |
index(str, beg=0, end=len(string)) | 跟find()方法一样,只不过如果str不在字符串中会报一个异常 |
isalnum() | 如果字符串至少有一个字符并且所有字符都是字母或数字则返回True,否则返回False |
isalpha() | 如果字符串至少有一个字符并且所有字符都是字母则返回True,否则返回False |
isdigit() | 如果字符串值包含数字,则返回T,否则返回F |
islower() | 如果字符串中包含至少一个区分大小写的字符,并且所有这些字符都是小写,则返回True,否则返回False |
isnumric() | 如果字符串中只包含数字字符,则T,否则F |
isspace() | 如果字符串中只包含空格,则返回True,否则F |
istile() | 如果字符串是标题化则返回T,否则返回F |
isupper() | 如果字符串中只包含大写的字符串,则返回T,否则返回F |
join(seq) | 以指定字符串作为分割符,将sql中所有的元素合并为一个新的字符串 |
len(string) | 返回字符串长度 |
ljuest(width, fillchar) | 返回一个原字符串左对齐,并且使用fillchar填充至长度width的新字符串,fillchar默认为空格 |
lower() | 转换字符串中的所有大写字符为小写 |
lstrip() | 去掉字符串左边的空格或指定字符 |
maketrans() | 创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标 |
max(str) | 返回字符串str中最大的字母 |
min(str) | 返回字符串中最小的字母 |
replace(old, new [,max]) | 将字符串中的str1替换成str2,如果max指定,则替换不超过max次 |
rfind(str, beg=0, end=len(string)) | 类似于find(),不过是从右边开始 |
rindex(str, beg=0, end=len(string)) | 类似于index,不过从右边开始 |
rjust(width [,fillchar]) | 返回一个原字符串右对齐,并且使用fillchar(默认空格)填充至长度width的新字符串 |
rstrip() | 删除原字符串末尾的空格 |
split(str="", num=string.count(str)) | 以str为分隔符截取字符串,如果num有指定值,则仅截取num+1个字符串 |
splitlines([keepends]) | 按照换行回车分隔,返回一个包含各行作为元素的列表,如果参数keepends为False,不包含换行符,如果为True,则保留换行符 |
startswith(substr, beg=0, end=len(string)) | 检查字符串是否是以指定字符串substr开头,如果是则返回True,否则返回False,如果beg和end指定,则在指定范围内检查 |
strip([chars]) | 在字符串上执行lstrip和rstrip |
swapcase() | 字符串中大写换小写,小写换大写 |
title() | 返回标题化的字符串,就是说所有的单词都是以大写开始,其余字母均为小写 |
translate(table, deletechars="") | 根据str给出的表,转换string的字符,要过滤掉的字符放到deletechars参数中 |
upper() | 转换小写为大写 |
zfill(width) | 返回长度为width的字符串,原字符串右对齐前面填充0 |
isdecimal() | 检查字符串是否只包含十进制字符,如果是返回true,否则返回false |
List
Python中使用最频繁的数据类型,List可以完成大多数集合类的数据结构实现。List中的元素类型可以不相同,支持数字,字符串甚至可以包含列表(嵌套)
列表是写在[ ]内之间,用逗号分隔的的元素列表。
列表支持索引和截取,列表被截取之后返回一个所需元素的新列表。索引值以0为开始值,-1为从末尾开始位置。
注意:
- 加号+是列表的连接运算符,星号*是重复操作
- List中的元素时可变的
- List内置了很多方法
- append()
- pop()
- List 截取的时候可以接收三个参数,第三个参数为截取的步长,如果第三个数字为负数,那么表示逆向读取
列表函数和方法
函数 | 说明 |
---|---|
len(list) | 列表元素个数 |
max(list) | 返回列表元素最大值 |
min(list) | 返回列表元素最小值 |
list(seq) | 将元组转换成列表 |
Python包含的方法
方法 | 说明 |
---|---|
list.append(obj) | 列表末尾添加新的对象 |
list.count(obj) | 统计某个元素在列表中出现的次数 |
list.extend(seq) | 在列表末尾一次性追加另外一个序列中的多个值,新列表扩展原来的列表 |
list.insert(index, obj) | 将对象插入列表 |
list.index(obj) | 从列表中找出某个值第一个匹配项的索引位置 |
list.pop(index=-1) | 移除列表中的一个元素(默认最后一个元素)并且返回该元素的值 |
list.remove(obj) | 移除列表中某个值的第一个匹配项 |
list.reverse() | 反向列表中元素 |
list.sort(key=None, reverse=False) | 对原列表进行排序 |
list.clear() | 清空列表 |
list.copy() | 复制列表 |
dictionary
字典是Python中的另外一个非常有用的内置数据类型。列表是有序的对象集合,字典是无序的对象集合。
字典的内置函数&方法
函数名 | 说明 |
---|---|
len(dict) | 计算字典元素个数,键的总数 |
str(dict) | 以字符串的形式输出字典 |
type(variable) | 返回输入的变量类型,如果是字典就返回字典类型 |
clear() | 删除字典内所有的元素 |
dict.fromkeys() | 创建一个新字典,以seq中元素作为字典的键,val为字典所有键对应的初始值 |
cope() | 返回一个字典的浅复制 |
get(key, default=None) | 返回指定键的值,如果值不存在,返回None |
in | key in dict 如果键在字典中,返回true,否则返回false |
dict1.items() | 一般列表的形式返回可遍历的(键,值)元组数组 |
dict1.keys() | 返回一个迭代器,可以使用list()转换为列表) |
dict1.setdefault(key, default=None) | 和get类似,如果键不存在于字典中,将会添加并将值设置为default |
Tuple
元组类型与列表类型类似,不同的是元组类型不能修改。元组写在小括号里面,元素之间使用逗号隔开。元组中的元素类型也可以是不同的
Tuple也可以被索引,索引从0开始,-1为末尾开始的位置,也是可以进行截取的。
虽然tuple的元素时不可以改变的,但是可以包含可变的对象,比如list。
tuple也是可以通过使用+操作符来进行
元组内置函数
方法 | 描述 |
---|---|
len(tuple) | 计算元组个数 |
max(tuple) | 返回元组中元素最大值 |
min(tuple) | 返回元组中元素最小值 |
tuple(iterable) | 将可迭代系列转换为元组 |
Set
集合是由一个或数个形态各异的大小整体组成的,构成集合的食物或对象称作元素或成员。Set的基本功能是进行成员关系测试和删除重复集合。
使用{} 或者set()来进行集合的创建。
集合内置方法
方法 | 描述 |
---|---|
add() | 为集合添加元素 |
clear() | 移除集合中的所有元素 |
copy() | 拷贝一个集合 |
difference() | 返回多个集合的差集 |
diffrence_update() | 移除集合中的元素,该元素在指定的集合内也存在 |
discard() | 删除集合中指定的元素 |
intersection() | 返回集合的交集 |
intersection_update() | 返回集合的交集 |
isdisjoint() | 判断两个集合是否包含相同的元素,如果没有,则返回T,否则返回F |
issubset() | 判断指定集合是否为该方法参数集合的子集 |
issuperset() | 判断该方法的参数集合是否为指定集合的子集 |
pop() | 随机移除元素 |
remove() | 移除指定元素 |
symmetric_difference() | 返回两个集合中不重复的元素集合 |
symmetric_difference_update() | 移除当前集合中在另外一个指定集合相同的元素,并将另一个指定集合中不同的元素插入到当前集合中 |
union() | 返回两个集合的并集 |
update() | 给集合添加元素 |
Python数据类型转换
有时候我们需要对数据内置的类型进行转换,数据类型的转换,只需要将数据类型作为函数名即可。
函数 | 描述 |
---|---|
int(x [,base]) | 将x转换成一个整数 |
float(x) | 将x转换成一个浮点数 |
complex(real [,imag]) | 创建一个复数 |
str(x) | 将对象转换成字符串 |
repr(x) | 将x对象转换成表达式字符串 |
eval(str) | 计算在字符串中的有效Python表达式,并且返回一个对象 |
tuple(s) | 将序列s转换成一个元组 |
list(s) | 将序列s转换成一个列表 |
set(s) | 转变为可变集合 |
dict(d) | 创建一个字典,d必须是一ge (key,value)的元组序列 |
frozenset(s) | 转变成不可变集合 |
char(x) | 将一个整数转换成一个字符 |
ord(x) | 将一个字符转换成他的整数值 |
hex(x) | 将一个整数转换成一个十六进制字符串 |
oct(x) | 讲一个整数转换成一个八进制字符串 |
Python的迭代器与生成器
迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束,迭代器只能往前不能后退。
迭代器有两个基本的方法: iter() 和next()
字符串,元组,列表都可以用于创建迭代器。
list = [1,2,3,4]
it = iter(list)
for x in it:
print(x,end" ")
创建一个迭代器
把一个类作为一个迭代器使用需要在类中实现两个方法__iter__()和__next__()
iter()方法会返回一个特殊的迭代器对象,这个迭代器对象实现了__next__()方法并且通过stopIteration异常标识迭代的完成。
next()方法会返回下一个迭代器对象。
class MyNum:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a +=1
return x
生成器不但可以用于for循环,还可以被next()函数不断调用并且返回下一个值。知道最后抛出StopInteration的错误,表示无法继续下一个返回值。可以直接被作用于for循环的对象统称为可迭代对象:Iterable,可以使用isinstance()判断一个对象是否是Iterable对象。
可以被next()函数调用并且不断返回下一个值的对象称为迭代器。生成器都是Iterable对象,但是list,dict,str虽然是Iterable对象,但是却不是Iterator。
Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并且不断返回下一个数据,直到没有数据时,抛出StopIteration错误,可以吧这个数据流看成一个有序序列,但是我们却不知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时,才会进行计算。
生成器
在Python中,使用了yield的函数被称为生成器。
生成器是一个返回迭代器的函数,只能用于迭代操作,生成器也是一个迭代器。在调用生成器运行的过程中,每次运行到yield时函数会暂停并且保存当前所有的运行信息,返回yield值。并且在下一次执行next()方法时,从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象。
如果列表元素可以按照某种算法推算出来,那么我们就可以在循环中不断推算出后续的元素,就不必再创建完成的List,可以节省很大的内存空间,Python中这种一边循环一边计算的机制,被称为生成器(Generator)
创建生成器
L = [x * x for x in range(10)]这个是列表生成式
如果我们把[]换成()就可以创建一个生成器
g = (x * x for x in range(10))
还有一种创建生成器的方式,就是使用yield关键字,当一个函数定制中包含了yield关键,那么这个函数就不再是一个普通函数,而是一个generator。
使用yield关键字定义的生成器,和函数的执行流程不一致,函数是每一行顺序执行,遇到return或者最后一条语句就返回。但是使用yield的生成器,是在每次调用next的时候执行。遇到yield就返回,再次执行的时候,则从上次返回的yield语句的地方继续执行。
比如:
def odd():
print("第一步")
yield 1
print("第二步")
yield 2
print("第三步")
yield 3
如此声明的odd函数就不在是一个普通的函数,遇到yield就会中断,下次又会继续执行。
Python的数据结构
列表方法使列表可以很方便的作为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后被释放(后进先出),用append()可以把一个元素添加到堆的栈顶,用不指定索引的pop()方法可以把一个元素从堆栈顶释放出来。
stack = [3,4,5]
stack.append(6) # 堆栈的添加
stack.pop() # 堆栈的释放
列表也可以用来作为一个队列来使用。
from collections import deque
queue = deque(["Er", "His", "MIC"])
queue.append("Terr")
queue.poplef()
Python 模块
__name__属性
一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入的时候,模块中的某一程序块不执行,我们可以使用__name__属性来使该程序块仅在该模块自身运行时执行。
if __name__=='__main__':
print("程序自身在运行")
else:
print('我来自另外一个模块')
每个模块都有一个__name__属性,当其值为__main__的时候,表明该模块自身在运行,否则是被引入。
dir()函数
内置函数dir()可以找到模块内定义的所有名称,以一个字符串列表的形式返回。
如果没有给定参数,那么dir()函数会罗列当前定义的所有名称。
Python的输入输出
Python有两种输出值的方式,表达式语句和print()函数
第三种方式是使用文件对象的write()方法,标准输出文件可以使用sys.stout引用
Python提供了input()内置函数从标准输入读入一行文本,默认的标准输入是键盘。
读和写文件
open(filename, mode) 会返回一个file对象
filename是包含了要访问的文件名称的字符串值
mode决定了打开文件的模式。
f = open('/temp/foo.txt', 'w')
f.write("Python sdasasasd")
f.close()
文件对象的方法
f.read()
为了读取一个文件的内容,调用f.read(size),这将读取一定数目的数据,然后作为字符串或字节对象返回,size是一个可选的数字类型的的参数,当size被忽略或者为负,那么该文件的所有内容都将被读取并且返回。
f.readline()
f.readline() 会从文件中读取单独的一行,换行符为‘\n’,如果返回一个空字符串,说明已经读到最后一行
f.readlines()
f.readlines()会返回文件中包含的所有行,
如果设置可选参数,则读取指定长度的字节,并且将这些字节按行分割
f.write()
f.write(string) 将string写入到文件中,然后返回写入的字符数。
f.tell()
f.tell()返回文件对象当前所处的位置,是从文件开头开始计算的字节数
f.seek()
如果要改变文件当前的位置,可以使用f.seek(iffset, from_what)函数
from_what的值,如果是0表示开头,如果是1,表示当前位置,2表示文件的结局
f,close()
用来关闭文件,释放系统的资源。
python的数据序列化和反序列化
python的pickle模块实现了基本的数据序列化和反序列化,通过pickle模块的序列化操作,我们能够将程序中运行的对象信息保存到文件中去,永久存储。
通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象
高阶函数
高阶函数的变量可以指向函数
abs(-10) # 表明我们调用abs()函数
# 而abs则表示函数本身
如果把函数本身赋给变量,那么该变量则指向函数本身,且可以通过变量进行调用。如果我们定义一个变量可以指向该函数的话,那么函数名又是什么,函数名就又成了指向该函数的变量,也就是说函数名也是变量。那么我们如果定义一个跟函数名相同的变量,就会发现定义的函数不能继续使用了。
可是我们会发现,变量可以指向函数,但是函数又是有可能有参数的。如果一个函数可以接收另外一个函数作为参数,这个函数就被称为是高阶函数。
def add(x, y, f):
return f(x) + f(y)
高阶函数就是让函数能够接收别的函数。
map/reduce
Python內建了map()和reduce()函数。
map
map() 函数接收两个函数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并且把结果作为新的Iterator返回。
map()传入的第一个参数是f,即函数对象本身,由于返回的是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。
map()作为高阶函数,将运算规则抽象了,可以计算任意复杂的函数。而且只需要一行代码。
reduce
reduce()把一个函数作用在一个序列上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积运算。
效果就是:reduce(f,[x1,x2,x3,x4]) = f(f(f(x1,x2),x3),x4)
比如:
from functools import reduce
def add(x, y):
return x+y
# 如果我们执行下面的数据
reduce(add, [1,3,5,7,9])
我们得到的结果将是
25
from functools import reduce
def fn(x, y):
return x*10 + y
def char2num(s):
digits = {'0':0, '1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9}
return digits[s]
reduce(fn, map(char2num, '13579'))
# map用于将13579转换成一个Iterator
# reduce 用于执行fn,将map输出的list转换成数字
13579
filter
filter()可以用来过滤序列
filter()把传入的函数依次作用于每一个元素,然后根据返回值是T或者F,来确定这个元素是留还是丢弃。
list中删除偶数,保留奇数
def is_odd(mn):
return n%2 ==1
list(filter(is_odd,[1,2,3,4,5,6,9,10,15]))
filter()这个高阶函数,关键在于正确实现一个“筛选”函数,filter函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。只有filter()在取结果的时候,才会真正筛选并每次返回下一个筛选出的元素。
返回函数
高阶函数除了可以接受函数作为参数外,还可以作为结果值返回
装饰器
函数也是一个对象,而且函数是可以被赋值给变量,所以通过变量也可以调用函数。
def now():
prin('当前时间')
f = now
f()
当前时间
如果我们想要增强函数的功能,比如在函数调用前后自动打印日志,但是又不想去修改now的函数的定义。这种在代码运行期间动态增加函数的方式,被称为装饰器。
本质上装饰器就是一个返回函数的高阶函数
定义方式比如
def log(func):
def wrapper(*args,**kw):
print("call %s()" %func.__name__)
return func(*args, **kw)
return wrapper
使用:
@log
def now():
print("2020-05-31")
当调用now函数的时候,不仅会运行now()函数本身,还会再now函数运行前打印一行日志。
将@log放到now()函数的定义的地方相当于执行了语句now = log(now)
又由于log()是一个装饰器,返回一个函数,所以原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新的函数,即在log中返回的wrapper函数
如果装饰器本身需要传入参数,那就要编写一个返回装饰器的高阶函数
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print("%s %s()" %(text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
import functools
def log(func):
@functools.wrap(func)
def wrapper(*args, **kw):
print("call %s()" %func.__name__)
return func(*args, **kw)
return wrapper
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print("%s %s()" %(text, func.__name__))
return wrapper
return decorator
偏函数
当函数的参数个数太多,需要简化的时候,使用functiontools.partial可以创建一个新的函数,这新的函数可以固定住原函数的部分参数,从而在调用时更简单。
import functools
int2 = functools.partial(int,base=2)
这样就是使用functools.partial()方法作用于int函数,并且将base参数固定为2,来生成int2函数。
面向对象
数据封装、继承和多态是面向对象程序设计的三个概念。
当子类继承父类的时候子类就具有了父类的能力,当A的子类B和C。当我们创建子类B和C的时候可以使用A来进行创建,都可以用A来操作 ,这时就是多态了。
对于Python动态语言来讲,我们并不一定要传入A的子类或者孙子类的类型。只要类中包含A中的方法,我们调用A中同名的方法的时候,也可以传入非A子类的类进行方法调用,这就是Python中的鸭子类型。动态语言的鸭子类型:一个对象只要“看起来像鸭子,走起路来像鸭子”那他就可以被看做是鸭子类型。
多重继承,通过多重继承,一个子类就可以同时获得多个父类的所有功能。