1.Python是一门面向对象的语言,在Python中一切皆对象
2.一个Python算法应该具有以下七个重要的特征:
1. 有穷性(Finiteness):算法的有穷性是指算法必须能在执行有限个步骤之后终止;
2. 确切性(Definiteness):算法的每一步骤必须有确切的定义;
3. 输入项(Input):一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输 入是指算法本身定出了初始条件;
4. 输出项(Output):一个算法有一个或多个输出,以反映对输入数据加工后的结果。没 有输出的算法是毫无意义的;
5. 可行性(Effectiveness):算法中执行的任何计算步骤都是可以被分解为基本的可执行 的操作步,即每个计算步都可以在有限时间内完成(也称之为有效性);
6. 高效性(High efficiency):执行速度快,占用资源少;
7. 健壮性(Robustness):对数据响应正确。
3.基础语法
3.1
可变数据对象:列表(list)和字典(dict)
不可变数据对象:整型(int)、浮点型(float)、字符串(string)和元组类型(tuple)
注:此处的可变和不可变,是指内存中的对象(Value)是否可以改变,对于不可变类型的对象,在对对象操作的时候,必须在内存中重新申请一块新的区域,即重新给一个新的地址用于存储;对于可变类型的对象,在对对象操作的时候,并不会重新申请新的地址,而是在该对象的地址后面继续申请即可,即address并不会改变,而是address的区域的大小会变长或变短。、
3.2
不可变数据类型:对象本身的值不可变,如果改变了变量的值,相当于新建了一个对象,而对于相同值的对象,在内存中只有一个对象。
可变数据类型:允许变量的值进行改变,对于变量给值的过程中,只是改变了变量的值,而不会新建一个对象,所以可变数据类型的意思就是说对一个变量进行操作时,其值是可变的,值的变化并不会引起新建对象,即地址是不会变的,只是地址中的内容变化了或者地址得到了扩充。,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。
3.3
浅拷贝:语法:copy.copy(),浅拷贝是创建了一个和原对象一样的类型,但是其内容是对原对象元素的引用。
深拷贝:语法:copy.deepcopy(),在内存中将所有的数据重新建立一份。
4.Python内置数据结构:
Python中最基本的数据结构是序列(sequence),Python包含 6 中内建的序列,包括列表、元组、字符串、Unicode字符串、buffer对象和xrange对象。
4.1 String
4.1.1、字符串的创建
将文本放在单引号,双引号和三引号之间
>>> str1 = ' hello, fanison '
>>> type(str1)
str
4.1.2、字符串的转义:
字符串的转义使用r
4.1.3、字符串的切片操作
索引运算符 s[i] 返回一个序列的元素i
切片运算符 s[i:j] 返回一个在字符串中从第i个元素开始到j-1之间的元素
扩展切片运算符 s[i:j:step] 在字符串中以step的步长从第i个到j-1个元素之间的元素,step为正数表示正着取,i
4.1.4字符串的相关方法:
s.index(sub [,start [,end]]) 找到指定字符串sub首次出现的位置
s.find(str,beg=0,end=len(string)) 找到字符串sub首次出现位置,与index不同是不报错而返回-1
s.upper() 将一个字符串转换为大写形式
s.lower() 将一个字符串转化为小写形式
s.join(t) 使用s作为分隔符连接序列t中的字符串 s.strip() 将s两边不显示的符号去掉之后返回(lstrip、rstrip)
s.split(t) 获取以字符t将s切割的列表
s.encode() 获取s的指定编码的bytes值
bytes.decode() 获取bytes的对应编码的字符串,在python2中使用decode函数
s.endswith(suffix,beg=0, end=len(string)) 检查中是否以suffix字符串结尾
4.2 list
变量:相当于是一个容器,每次只能存储一个数据
作用:相当于是一个容器,可以同时存储多个数据
本质:一种有序的集合【有序:数据的存放顺序和底层存储的顺序是相同】
列表中的元素本质存储的是一个变量【引用】,列表是可变的【一个列表一旦被定义,则在代码运行的过程中,其中的元素的值可以随时发生改变】
4.3 tuple
和列表类似,本质是一种有序的集合
元组和列表的不同之处:
a.定义不同:列表[] 元组()
b.是否能够修改:列表可以进行增加或者删除元素的操作,但是,元组一旦被定义之后,其中的元素将不能进行任何的更改
4.4 dict 常用
也是一种存储数据的方式,但是字典是无序的,
类似于list或者tuple,但是,字典采用键-值对的方式存储数据
作用:具有极快的查找速度
4.4.1 key的特点
a.字典的key是唯一的【key不允许重复】
b.key必须为不可变的数据
list是可变的,不能用来当做key
tuple,数字型,字符串,布尔值都是不可变的,可以被充当key
4.4.2.字典的遍历
#4.1直接遍历key 掌握
for key in dict1:
print(key,dict1[key])
# print(dict1.keys())
# print(type(dict1.keys())) #
for key in dict1.keys():
print(key,dict1[key])
#4.2直接遍历value
for value in dict1.values():
print(value)
#4.3,遍历的是键值对的编号和key
for i,element in enumerate(dict1):
print(i,element)
#4.4同时遍历key和value 掌握
for key,value in dict1.items():
print(key,value)
4.4 set
集合:不允许重复元素,而且进行交集以及并集的运算
表示:{}
和dict之间的关系:set中只是存储了key
本质:无序且无重复元素的集合
4.5 list、tuple、dict、set的区别和联系:
a、定义方式:list:[]、tuple:()、dict:{}、set:{}
b、是否有序:list:有序,tuple:有序,dict:无序,set:无序
c、是否允许出现重复元素:list:允许,tuple:允许,dict:key键值不允许,但是value的值允许,set:不允许
d、都属于可迭代对象
e、set相当于存储了字典中的key
f、可以向互转化
5.生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象。
a = (i for i in range(1,10)) #将列表生成试外部的中括号改为小括号,就能将生成式转化为生成器。
next(a),a.__next__() #生成器的取值方式只能使用next的方法。
def num():
a,b = 0,1
for i in range(10):
yield b #生成关键字yield,有yield的关键字的代码块就是yield的生成器。当运行到yield时代码就会停止,并返回运行结果,当在次运行时依旧是到yield停止,并返回结果。 切记:生成器只能使用next方法。
a,b = b,a+b
temp = yield b #这里并不是变量的定义,当运行到yield时就会停止,所以当运行到等号右边的时候就会停止运行,当在次使用next的时候,将会把一个None赋值给temp,因为b的值已经在上轮循环中输出。这里可以使用num().send()方法将一个新的值赋值给temp。
a = num() #将生成器赋值给变量a。
for n in a: #生成器可以使用for循环使用,并且不会出错。
print(n)
6. 迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 和 next()。
字符串,列表或元组对象都可用于创建迭代器
for i in '',[],(),{},{:} #可以for循环的对象是可迭代对象。
a = (x for i in range(100)) #列表生成式,把中括号改为小括号就可以变为一个列表生成器,是可迭代对象。
from collections import Iterable #如果想验证是否是可迭代对象,可以使用isinstance()判断是否是可迭代对象。
isinstance('abc',Ierable) #判断语法
a = [1,2,3,4,5]
b = iter(a) #使用iter()方法可以将可迭代对象转换为可迭代对象。
注意:生成器是可迭代对象,迭代器不一定是生成器。并且迭代器无法回取,只能向前取值。
注意:一个对象具有 iter 方法的才能称为可迭代对象,使用yield生成的迭代器函数,也有iter方法。凡是没有iter方法的对象不是可迭代对象,凡是没有__next__()方法的不是是生成器。(这里的方法都是魔法方法,是内置方法,可以使用dir()查看)
7. 闭包
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
注意:当一个函数定义在另一个函数内,且使用到了外部函数的参数。整个代码块称为闭包。当外部参数确定时,内部函数参数可以反复调用。
def num(num): #定义函数
def num_in(nim_in): #定义函数
return num + num_in #返回两个参数的和。
return num_in #返回内部函数的引用。(变量名)
a = num(100) #将参数为100的函数num接收,并赋值给a,只不过这个返回值是一个函数的引用。等于 a = num_in,注意这里接收的不光是函数本身,还有已经传递的参数。
b = a(100) #调用函数a,即num_in,并传递一个参数100,返回值给b。
8. 装饰器
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。
装饰没有参数的函数
def function(func):#定义了一个闭包
def func_in():#闭包内的函数
print('这里是需要装饰的内容,就是需要添加的内容')
func()#调用实参函数。
return func_in
def test():#需要被装饰修改的函数。
print('无参函数的测试')
test = function(test)#装饰器的原理就是将原有的函数名重新定义为以原函数为参数的闭包。
test() 这里再次掉用test()的时候,其实是将会调用闭包内的函数func_in()。所以将会起到装饰修改的作用,最后会再次调用原函数test()。
@function #装饰器的python写法,等价于test = function(test),并且无需调用当代码运行道这里,Python会自动运行。
def test():
print('无参函数的测试')
test()#这里再次调用函数时,将会产生修改后的效果。
装饰带有参数的函数
def function(func):#定义了一个闭包
def func_in(*args,**kwargs):#闭包内的函数,因为装饰器运行的实则是闭包内的函数,所以这里将需要有形参用来接收原函数的参数。
print('这里是需要装饰的内容,就是需要添加的内容')
func(*args,**kwargs)#调用实参函数,并传入一致的实参。
return func_in
@function #装饰器的python写法,等价于test = function(test) .
def test():
print('无参函数的测试')
test(5,6)#这里再次掉用test()的时候,其实是将会调用闭包内的函数func_in()。所以将会起到装饰修改的作用,最后会再次调用原函数test()。
装饰带有返回值的函数
def function(func):#定义了一个闭包
def func_in(*args,**kwargs):#闭包内的函数,因为装饰器运行的实则是闭包内的函数,所以这里将需要有形参用来接收原函数的参数。
print('这里是需要装饰的内容,就是需要添加的内容')
num = func(*args,**kwargs)#调用实参函数,并传入一致的实参,并且用变量来接收原函数的返回值,
return num#将接受到的返回值再次返回到新的test()函数中。
return func_in
@function
def test(a,b):#定义一个函数
returna+b#返回实参的和
通用装饰器
def function(func):#定义了一个闭包
def func_in(*args,**kwargs):#闭包内的函数,因为装饰器运行的实则是闭包内的函数,所以这里将需要有形参用来接收原函数的参数。
print('这里是需要装饰的内容,就是需要添加的内容')
num = func(*args,**kwargs)#调用实参函数,并传入一致的实参,并且用变量来接收原函数的返回值,
return num#将接受到的返回值再次返回到新的test()函数中。
return func_in
带有参数的装饰器
def func(*args,**kwags):
def function(func):#定义了一个闭包
def func_in(*args,**kwargs):#闭包内的函数,因为装饰器运行的实则是闭包内的函数,所以这里将需要有形参用来接收原函数的参数。
print('这里是需要装饰的内容,就是需要添加的内容')
num = func(*args,**kwargs)#调用实参函数,并传入一致的实参,并且用变量来接收原函数的返回值,
return num#将接受到的返回值再次返回到新的test()函数中。
return func_in
return function
@func(50) #这里会先运行函数func,并切传入参数,之后会再次运行闭包函数进行装饰, @func(50)>>@function,然后将由@function继续进行装饰修改。
def test(a,b):
print('这是一个函数')
return a+b
classTest(object):#定义一个类
def__init__(self,func):
self.__func = func
def__call__(self):#定义call方法,当直接调用类的时候,运行这里。
print('这里是装饰的功能')
self.__func()
t = Test()#实例化对象
t()#调用类,将会调用call方法。
@Test #类装饰器等于test = Test(test),将函数test当作参数传入类中的init方法,并将函数名赋值给私有属性__func,当函数test被调用的时候,其实是运行Test类中的call方法.
def test():
print('被装饰的函数')
test()#这里调用的不在是函数test,而是实例对象test的call方法,会先进行装饰,然后再调用私有属性__func(),__func 其实就是被装饰的函数test。