python 高级
包和模块
模块:
模块就是一个保存了python代码的文件,模块能定义函数,类和变量。模块也能包含可执行的代码。
包:
多个关系密切的模块组织成一个包,以便于维护和使用,创建一个名字为包名字的文件夹并且在该文件下创建一个__init__.py文件就定义了一个包。
包下面的文件夹则为模块,如果某个文件夹下面包含有__init__.py那么这个文件为包的子包。
引入模块:
import 包路径 . 模块
from 包路径 impoyt 模块
载入所有对象到当前名存空间
__init__.py文件中写入__all__语句,__all__里面写入所有要导入的对象
from 包路径 import *
==与is的区别和联系
==是比较变量的值
is比较变量的内存地址
copy拷贝
引入拷贝模块:import copy
浅拷贝: copy . copy()对于一个对象顶层的拷贝
如果拷贝对象有子层,则拷贝后子层的数据机会随着原来子层数据的变化而变化
例:
>>>a = [1,2,3,4,[111,222]]
>>>b = copy copy(a)
>>>b = [1,2,3,4[111,222]]
>>>a[4].append(333)
>>>b = [1,2,3,4,[111,222,333]]
但是顶层不会变化
>>>a.append(5)
>>>a = [1,2,3,4,[111,222,333],5]
>>>b = [1,2,3,4,[111,222,333]]
深拷贝:copy . deepcopy() 对对象所有层次的拷贝
不管后面原对象a数据如何变化,b都不会改变
property
面向对象中替换setter和getter方法
@property成为属性函数,可以对属性赋值时做必要的检查,并保证代码的清晰短小
将方法转换为只读
重新实现一个属性的设置和读取方法,可做边界判定
classMoney(object):
def __init__(self):
self.__money =0
@property
def money(self):
returnself.__money
@money.setter
def money(self, value):
ifisinstance(value, int):
self.__money = value
else:
print("error:不是整型数字")
生成器
一边循环一边计算的机制为生成器:generator
创建一个列表,只在需要的时候显示所需数据,其他的数据看不到,起到节省内存的作用
创建生成器的方法:
1、与生成一个列表的方法相似:
列表:a = [x for x in range(5)]
生成器:a = (x for x in range(5))
显示生成列表的数据next(a)
生成器保存的是算法,每次调用next(G),就计算出G的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的异常。当然,这种不断调用next()实在是太变态了,正确的方法是使用for循环,因为生成器也是可迭代对象。所以,我们创建了一个生成器后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration异常。
2、yield方法:
def fblq(max):
n,a,b =0,0,1
whilen < max:
print(b)
a,b = b,a+b
n +=1
res = fblq(5)
要把fblq函数变成generator,只需要把print(b)改为yield b就可以了
def fblq(max):
n,a,b =0,0,1
whilen < max:
yield b //生成生成器 生成器就是返回值 next时,函数执行,当遇到yield关键字时,
a,b = b,a+b // 返回yield的值,下一次执行yield的时候,函数从yield后面开始执行
n +=1
res = fblq(5)
我们在循环过程中不断调用yield,就会不断中断。当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。
执行到yield时,gen函数作用暂时保存,返回i的值;temp接收下次c.send("python"),send发送过来的值,c.next()等价c.send(None)
def scq1():
n = 10
while n < 20:
temp = yield n
print(temp)
if temp == 1:
print("查询了一条数据")
elif temp == 2:
print("更新了一条数据")
elif temp == 3:
print("删除了一条数据")
n += 1
res = scq1()
res.send(3)
生成器的特点:
1.节约内存
2.迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的
迭代器
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
能够for循环一定能被迭代,但不一定是迭代器
以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
判断是否可以迭代:
isinstance(obj,class)
isinstance([ ] , Iterable)
可以使用isinstance()判断一个对象是否是Iterator对象
把list、dict、str等Iterable变成Iterator可以使用iter()函数:isinstance(iter([]), Iterator)
总结:
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
目的是在使用集合的时候,减少占用的内容。
函数
递归函数:
def sum(max):
if max == 1:
return 1
return max*sum(max-1)
a = sum() //调用函数
a = sum //将函数赋值给变量,变量也变为一个函数
函数作为参数:
def show(msg,fn):
print(msg)
fn()
def f():
print("这是个参数函数")
show("hello,word!",f)
运行结果:hello,word! 这是个参数函数
匿名函数:
lambda:
lambda x , y : x+y <=> def sum(x,y):
return:x+y
匿名函数可做参数传递:
def show(msg,fn):
print(msg)
fn()
show("hello,word!" , lambda:print("这是个匿名函数"))
闭包:
#定义一个函数
def test(number):
#在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
def test_in(number_in):
print("in test_in函数, number_in is %d"%number_in)
return number+number_in
#其实这里返回的就是闭包的结果
return test_in
闭包就是让局部变量具有全局变量一样,被调用后不会消失的特点,但是又具有局部变量自身不会被随意调用的特性。