Catherine 成长记第二篇

小白成长记第二篇

【1】.变量-------存储数据的
作用域--------有效的作用的范围
作用域由什么决定?
由变量所在的位置决定的·

【2】.作用域的产生
只能在模块,类,函数中产生
if else for while 是没有作用域的

【3】.作用域的类型
局部作用域--------定义在函数内部的变量
全局作用域---------定义在函数外的变量
嵌套作用域
内置作用域

【4】.搜索变量名的优先级 LEGB法则
局部>嵌套>全局>内置
L E G B
举例:# num18=20 #全局作用域

def outer():

num19=30 #嵌套作用域

def inner():

num20=40 #局部作用域

print(num18+num19+num20)

inner()

print(sum([1,5,7,8])) #内置作用域

outer()

【5】.global nonlocal
global------在函数内部修改全局变量的
nonlcal-------在嵌套函数中,内部函数修改外部函数的临时变量

【6】.python中的内存管理机制

当我们创建变量的时候 python的内存管理机制,会给这个变量的值创建一个内存地址,
那么这个变量就是引用这个内存地址

用id查看内存地址

当一个值 引用计数为0 时,他的内存地址就会被垃圾回收机制回收
引用的次数--------引用计数
举例:
name=“李”
name1=name #吧name赋值给name1
print(id(name)) #id会是一样的
print(id(name1)) #id会是一样的

【7】深拷贝和浅拷贝 ,拷贝----复制—copy
1.导模块
2.浅拷贝 copy.copy()
对不可变数据类型进行拷贝 内存地址是一样的
对可变数据类型进行拷贝 内存地址是不一样的
浅拷贝只会拷贝引用,不会拷贝内容

举例:import copy

alist=[11,22]
alist1=[33,44]
alist2=[alist,alist1]

print(id(alist)) #内存地址没有变化

print(id(alist2[0])) #内存地址没有变化

alist4=copy.copy(alist2) #对alist4进行浅拷贝
print(id(alist2)) #拷贝完以后有两个内存地址
print(id(alist4)) #alist4已经被浅拷贝了,会重新生成一个地址

alist.append(55) #向alist追加内容
print(id(alist),alist) #查看内存地址并输出alist内容
print(id(alist4[0]),alist4[0])

3.深拷贝 copy.deepcopy()
深拷贝会复制一个和原变量一模一样的变量
并且对任意一个修改都不会影响另一个,内存地址不相同
举例:alist=[11,22]
alist1=[33,44]
alist33=[alist,alist1]

alist4=copy.deepcopy(alist33) #深拷贝,重新创建一个内存地址,修改任意一个变量内容,另外一个变量内容不受影响
print(id(alist33)) #内存地址不一样
print(id(alist4)) #内存地址不一样

alist.append(55)

alist4.clear() #清空深层拷贝
print(alist) #输出原列表
print(alist4) #输出拷贝的清空列表

【8】== 和 is
==---------只比较内容,不比较内存地址 -----浅拷贝
is----------比较内容 和内存地址,是否都相同-----深拷贝
举例:alist=[11,22]
alist1=[33,44]
alist33=[alist,alist1]

alist4=copy.copy(alist33) #浅拷贝
alist5=copy.deepcopy(alist33) #深拷贝

if alist5 is alist33: #判断内存地址和内容是否一样
print(“我们一样的”)
else:
print(“我们不一样”)

迭代器
1.什么是迭代,迭代又可以叫遍历
能被遍历的数据类型有?
str list dict set tuple

2.什么是可迭代对象?
能被for 遍历的对象就是可迭代对象-----Iterable(可迭代对象)

3.如何判断一个对象是否是可迭代对象?
【1】能被for遍历
【2】用isinstance(o,t)----o代表object要判断的对象,t代表type,判断的类型,iterable/iterator
如果返回Ture ,代表是可迭代对象
如果返回False,代表不是可迭代对象
举例:
from collections.abc import Iterable #导包

list_4=[1,2,3,4]
print(isinstance(list_4,Iterable)) #可迭代对象
print(isinstance(5,Iterable)) #不可迭代对象

4.能不能自己创建一个可迭代对象?--------可以
【1】通过类
【2】类里必须有__iter__方法,也就是说,具备了__iter__方法,就是可迭代对象
举例:
from collections.abc import Iterable
class demo():
def init(self): #定义一个魔法方法
self.list1=[]
def add(self,item): #定义一个方法,然后在列表里追加元素,创建一个形参
self.list1.append(item)
print(self.list1)
def iter(self): #添加一个魔法属性以后,类里面的对象就是可迭代对象了
pass

li=demo()
li.add(5) #在列表中添加一个元素
li.add(6) #在列表中添加一个元素
li.add(7) #在列表中添加一个元素
print(isinstance(li,Iterable)) #判断是否是可迭代对象

4.迭代器?—Iterator
能够帮助我们记录遍历当前元素的“人”

5.可迭代对象是迭代器吗?
不是

8.判断一个对象是否是迭代器
isinstance(o,t)

9.如何吧可迭对象变成迭代器?
1.对已知数据类型转换
使用iter() 和next()
2.对自定义的对象进行转换
定义:一个具备__iter__方法和__next__方法的对象就是迭代器
格式:在类里加一个__next__
10.迭代器的输出方式
1.使用next()函数
2.for 遍历
3.用list/tuple强转

举例:
list3=[1,2,3,4]
list4=iter(list3) #用iter强转以后迭代对象就是迭代器了
print(isinstance(list4,Iterable)) #判断对象是否是迭代对象
print(isinstance(list4,Iterator)) #判断对象是否是迭代器

print(next(list4)) #输出迭代器的内容,要用next,一次只能输出一个

print(next(list4)) #输出迭代器的内容,要用next,一次只能输出一个

print(next(list4)) #输出迭代器的内容,要用next,一次只能输出一个

print(next(list4)) #输出迭代器的内容,要用next,一次只能输出一个

for i in list4: #循环遍历迭代器,可以输出每个元素

print(i)

print(list(list4)) #将迭代器强转成列表输出

print(tuple(list4)) #将迭代器强转成元祖输出

10.for循环的本质
1.先通过iter()获取可迭代对象的迭代器
2.通过next()获取值,并且把值赋给i
3.当遇到StopIteration就停止循环了
for i in range(1,10):
print(i)
11.用迭代器实现婓波那契数列
[0, 1, 1, 2, 3, 5, 8, 13]—前两数相加就是等于第三数就是婓波那契
举例:
class feibo():
def init(self,n):
self.n=n
self.num1=0
self.num2=1
self.index=0 #下标
def iter(self):
return self
def next(self):
if self.index<self.n: #下标小于个数
num=self.num1 #用来存放,斐波那锲数
self.num1,self.num2=self.num2,self.num1+self.num2
self.index+=1
return num
else:
raise StopIteration #直接一次结束,然后执行下一次
li=feibo(8)
print(list(li)) #输出返回的值,num

1.了解生成器--------generator
定义:生成器是特殊的迭代器,一边循环一边计算的机制
查看迭代器的方式你跟不能用来查看生成器?
【1】next()
【2】for 遍历
【3】list()/tuple()

2.创建生成器
【1】列表推导式的[]换成()
举例:print(list(i for i in range(1,10))) #必须要用迭代器的输出方式强转,不然会输出一个地址
【2】将函数中的return换成yield
如果一个函数中有yield,,那么这个函数就是生成器

3.yield的作用
【1】将函数挂起
【2】将返回值返回

4.用生成器实现斐波那契数列
举例:
def feibo():
a,b=0,1
for i in range(10): # 循环10次
yield a #将a返回值返回,或者挂起
a,b=b,a+b #替换位子
li=feibo() #创建一个对象
print(list(li)) #将对象里的返回值强转输出

5.唤醒生成器的三种方式
【1】next()
【2】next
【3】send()给生成器传值
举例:
第一种:def func1():
for i in range(1,10):
num=yield i #将生成器返回的值给num
print(num) #输出send添加的元素,和yield原有的返回值
f=func1()
print(next(f)) #一次调用一个数
print(f.send(“哈哈”)) #给生成器添加元素,send也会激活生成器
print(next(f)) #再次输出一个生成器的值
print(next(f))

第二种:
def feibo():
a,b=0,1
for i in range(10): # 循环10次
num=yield a #将a返回值返回,或者挂起,并传给num
print(num) #输出生成器原有的值和send传来的值
a,b=b,a+b #替换位子
li=feibo() #创建一个对象

print(list(li)) #将对象里的返回值强转输出

print(next(li))
print(li.send(“哈哈”)) #给生成器传值
print(next(li)) #再次唤醒生成器,传值只传了一次所以下面会显示none
print(next(li))
print(next(li))

6.【高阶函数】
定义:把一系列的运算过程换成嵌套函数的调用,就是一个函数把另一个函数做为参数传入
【1】.map(func,Iterable)
用法:将可迭代对象里的每一个元素,依次执行一遍函数,并且将结果返回到一个迭代器里面。
举例:def func(x):
return x*x
print(list(map(func,range(1,5))))
【2】reduce()
用法:将可迭代对象里面相邻的两个参数传到函数里执行,将结果与第三个数在放到函数里执行,依此类推,
结果是一个值
【3】sorted()
定义:如果可迭代对象里有负数,并且有绝对值,name排序的时候根据附属的绝对值进行排序。
列表排序
使用sort 排序,默认是正序,倒序格式:列表名.sort(reverse=True)
【4】filter()
格式:filter(func,Iterable)
作用:将可迭代对象里的每一个元素依次放函数中去判断,是否满足条件,将满足条件的放在一个迭代器中返回
举例:
#key=abs,绝对值是正数的不变,负数的改为正数
list_1=[1,8,4,3,54,-14,7,-8]
print(sorted(list_1,key=abs,reverse=True)) #倒序排序,有负数改为正数

返回函数
定义:一个函数吧另一个函数作为返回值返回
举例:# 返回函数

定义:一个函数吧另一个函数作为返回值返回

def outer(): #外部函数

print(“11111”)

def inner(): #内部函数

print(“22222”)

return inner #内部函数返回值

outer()() #第一个括号调用外部,第二个括号调用内部

程序入口if name == ‘main’:
作用:可以将调用的代码写到程序入口里面,他可以按照调用的先后顺序进行调用函数内容,更好的排序

闭包
定义:在嵌套函数中,内部函数引用外部变量的值,修改外部变量的值,并且输出这个变量的值
举例:def a(): #定义一个函数
c=100 #定义一个外部变量
def b(): #定义一个内部函数
nonlocal c #内部修改外部的临时变量
c=500 #进行更改
print© #输出更改完的临时变量
return b #返回这个内部函数值
a()() #调用外部和内部函数

装饰器
定义:在不修改原函数代码的前提下,给函数添加新功能
举例:
#写一个函数func,先输出hello,暂停一秒钟,在输出word,用装饰器
import time

def outer(func): #定义一个装饰器
def inner(): #定义一个函数
start=time.time() #程序开始时间
func() #调用装饰器
end=time.time() #程序结束时间
print(“运行时间是:”,end-start) #输出程序开始到结束的时间
return inner #返回内函数

@outer #装饰器函数名
def func(): #添加内容
print(“hello”)
time.sleep(1) #停一秒后输出word
print(“word”)

双层装饰器的流程
1.开始的时候执行外部函数,顺序从下往上
2.执行嵌套函数,顺序从上往下
3.执行原函数
4.结束的时候,顺序从下往上
举例:
def dec1(func):
print(“1111”)
def one():
print(“2222”)
func()
print(“3333”)
return one
def dec2(func):
print(“aaaa”)

def two():
    print("bbbb")
    func()
    print("cccc")
return two

@dec1
@dec2
def test():
print(“test test”)
test()

偏函数
1.用partial 创建一个 偏函数
函数名=partial(原函数名,参数固定值)
参数必须是最后一个形参
只需要调用新函数即可
举例:
from functools import partial #需要导包
def func(a,b):
return a*b
n=partial(func,b=10) #只能用最后的给固定值
print(n(10)) #输出返回的值,然后10是a的实参

递归
定义:在函数内部调用自身,也就是return后面跟自己的函数名
求阶乘
3!=123
5!=123
举例:#偶数和

def sum(n):

if n==100: #判断到100的时候结束

return 100 #返回100

else:

return n+sum(n+2) #不是100的时候就是相加

print(sum(0)) #输出返回的sum和

数据结构
定义:数据结构是计算机存储,组织数据的方式。
分类:
1.逻辑结构------面向问题的,元素之间的关系
分类:线性,图形,树形,集合

2.物理结构,又叫存储结构------面向计算机的,目的都是将数据及逻辑关系,存储到计算机的内存中
定义:数据的逻辑结构在计算机中的存储形式。
分类:顺序存储结构,链式序存储结构

算法
定义:解决特定问题求解步骤的描述。
算法的基本特性:
【1】输入,算法具有零个或多个输入
【2】输出,至少有一个或多个输出
【3】有穷性,算法在执行有限步后能够自动结束,不会出现无限循环
【4】确定性,算法的每一步都具有确定的含义,不会出现二义性
【5】可行性,算法的每一步都能够通过执行有限次操作完成

算法的复杂度:
时间复杂度
计算算法运行起来所需要的时间
空间复杂度
计算算法所需要的内存时间
评价一个算法的好坏重要依据,时间复杂度

时间复杂度 大O表示法
list 中的时间复杂度
append() o(1)
pop() o(1)
pop(i) o(n)
reverse o(n)
sort o(n log n)

字典的时间复杂度
delete o(1)

线性表
1.定义:具有零个或多个数据元素的有限序列

2.特征:第一个元素没有前驱元素
最后一个元素没有后继元素
其他的元素只有一个前驱和一个后继元素

3.操作:插入,删除,查找

4.分类:
1.顺序表------存储结构连续
定义:在计算机的内存中,以一组地址连续的存储单元,依次存储数据元素的线性结构。
优缺点:
优点:支持随机访问
缺点:插入和删除需要移动大量的元素,造成存储空间的碎片。
在python中的应用:列表/元祖
时间复杂度:
访问 o(1)
插入删除 o(n),最后一个元素和第一个元素是o(1)

2.链表------逻辑连续,存储结构不连续
定义:
1.常见的数据结构,是一种线性表
2.存储单元不在连续
分类:单向链表,单向循环链表,双向链表
优缺点:
优点:插入删除比较方便
缺点:不支持随机访问
时间复杂度:
访问 o(n)
插入删除 o(n)

栈------好比一个弹夹
定义:只允许在表尾进行插入删除的线性表
特征:后进先出

队列
定义:允许在一端插入另一端删除的的线性表,队列是先进先出。


节点的度:一个节点含有子树的个数,称为该节点的度。
树的度:一棵树中,最大的节点的度称为树的度。
叶节点/终端节点:度为0的节点
父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点。
子节点:一个节点含有的子数的节点称为该节点的子节点。
兄弟节点:具有相同父节点的节点故称为兄弟节点。
节点的层次:从根开始定义起,根为第1层,跟的子节点为第2层,以此类推
树的高度或深度:树中节点的最大层次
堂兄弟节点:父节点在同一层的节点互为堂兄弟
节点的祖先:从根到该节点所经分支上的所有节点
子孙:以某个节点为根的子树中任一节都称为该节点的子孙
森林:由m(m>0)根互不相交的树的集合称为森林

树的分类:有序树,无序树,二叉树,完全二叉树,平衡二叉树,排序二叉树,霍夫曼树,B树
二叉树分类:1.完全二叉树:对叶节点没有要求 2.满二叉树:除了叶节点,其他的节点都有左右子树
遍历:
【1】深度优先遍历:
先序:根节点—左子树—右子数
A–B--D–H--I–E--J–C--F–G-----从上到下
中序:左子树–根节点—右子数----从下到上
H–D--I–B--J–E--A–F--C–G
后序:左子树—右子树----根节点----从下到上
H–I--D–J--E–B--F–G--C–A

广度优先遍历----又叫层次遍历
从上往下,从左到右依次输出

树的存储:顺序存储,链序存储------二叉树存储方式

树的应用:路由协议,mysql数据库索引,文件系统的目录结构,AI算法,xml/html

正则表达式
用到的方法
match(“正则表达式”,“字符串”)从头开始匹配*********
1.匹配单子符 ------一个字符

. ------- 匹配任意字符,除了\n
[ ] -------- 匹配[ ]中列举的字符
\d --------匹配数字0-9-------digit
\D---------匹配非数字
\w--------匹配单词字符------word
\W--------匹配非单词字符–中文字不行
\s--------匹配空格 ,tab键和空格键-----spac
\S--------匹配非空格

2.匹配多字符
±-----匹配前一个字符串出现1次或无限次—至少出现1次
*--------匹配前一个字符出现0次或无限次—可有可无
?-------匹配前一个字符出现0次或1次
{m}----匹配前一个字符串出现m次
{m,} ------匹配前一个字符至少出现m次
{m,n}------匹配前一个字符至少出现m次,最多出现n次

^-------匹配以什么开头
$------------匹配以什么结尾
|---------匹配左右任意一个
()---------匹配分组

2.search()
从起始位置开始匹配,直到遇见匹配成功才会结束,只返回第一个·

3.findall()
从起始位置开始匹配,直到把所有匹配成功的字符串找出来才会结束
会把结果放到一个列表中

线程
1.多任务
定义:同一时间执行多个任务
方式:
【1】并行:多个任务同时执行
【2】并发:多个任务交替执行

在python中如何创建线程
1.导包threading import threading
2.需要有函数 至少两个或多个

3.在python中如何创建线程
【1】导包threading------import threading
【2】需要有函数 至少两个或多个
【3】变量名=threading.Thread(target=函数名,args/kwargs)
【4】变量名.start()-----开启线程

4.主线程
子线程--------程序员自己创建的线程
主线程不会等待子线程结束在结束----如何解决?
用join()----实现主线程等待子线程结束在结束

5.多线程执行起来是无序的
6.线程之间共享全局变量
7.线程之间参数的传递

守护线程
守护主线程
当一个线程是守护线程时,主线程结束,守护线程才会结束
创建守护线程的方式
1.t=Thread(target=func,daemon=True) #守护主线程的格式
2.t.setdaemon(True)

互斥锁
线程之间是共享全局变量的
为了防止多个线程同时修改全局变量,就要用到互斥锁

互斥锁的创建
1.用threading中的Lock()
变量名=threading.Lock()

2.上锁look.acquire()
3.解锁lock.release()

死锁
等待释放锁的过程
避免死锁的方法:
1.设置超长的等待时间
2.用银行家算法

同步 异步 — 等

并发 并行 ---- 同时

阻塞 非阻塞

守护线程

‘’’
1.并发和并行
  并发:在操作系统中,是指一个时间段中有几个程序都处于已启动到运行完毕之间,且这几个程序都是在同一个处理
机上运行,但任一个时刻只有一个程序在处理机上运行。简言之,是只系统具有处理多个任务的能力。
  并行:当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程是,另一个CPU可以执行另
一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。简言之,是指系统具有用时处理多个任务的能力。

2.同步和异步

同步:当进程执行IO(等待外部数据)的时候,-----等。同步(例如打电话的时候必须等)

异步:当进程执行IO(等待外部数据)的时候,-----不等,去执行其他任务,一直等到数据接收成功,再回来处理。异步(例如发短信)
当我们去爬取一个网页的时候,要爬取多个网站,有些人可能会发起多个请求,然后通过函数顺序调用。执行顺序也是先调用先执行。效率非常低。

3.阻塞和非阻塞
  阻塞:只要有一丁点阻塞,就是阻塞IO。比如一个线程占用了临界区资源,那么其它所有需要这个资源的线程就
必须在这个临界区中进行等待,等待会导致线程挂起。这种情况就是阻塞,此时,如果占用资源的线程一直不愿意释放资源,那么其它所有阻塞在这个临界区上的线程都不能工作。
  非阻塞:而非阻塞允许多个线程同时进入临界区。

守护线程
守护线程的理解:
如果当前python线程是守护线程,那么意味着这个线程是“不重要”的,“不重要”意味着如果他的主进程结束了
但该守护线程没有运行完,守护进程就会被强制结束。如果线程是非守护线程,那么父进程只有等到守护线程运行完毕后才能结束。
在python中,线程通过threadName.setDaemon(True|False)来设置是否为守护线程。

守护线程的作用:
守护线程作用是为其他线程提供便利服务,守护线程最典型的应用就是 GC (垃圾收集器)。
守护线程的特点:
只要当前 主线程中尚存任何一个非守护线程没有结束,守护线程就全部工作;
只有当最后一个非守护线程结束时,守护线程随着主线程一同结束工作。
‘’’

进程的概念
定义:一个程序运行起来,所占用的资源,是操作系统资源分配的基本单位
2.一个程序至少有一个进程、一个进程至少有一个线程,线程依附在进程中,没有进程就没有线程
3.进程的状态:就绪态、执行态、等待态
4.线程和进程的对比
1.线程所需要的资源比较小,进程需要的资源比较多
2.一个程序至少有一个进程、一个进程至少有一个线程
3.进程拥有自己的内存单元,线程共享进程的内存单元
4.线程不能独立执行

5.创建线程
1.导包-----import multiprocessing/from multiprocessing import Process
2.创建任务—函数
3.multiprocessing.Process(target=函数名)
4.开启进程 start()
5.join()
6.进程之间是否共享全局变量?-----No
7.打印进程号
os.getpid()
8.terminate()------立即结束子进程

进程间的通信--------消息队列
Process()
queue-------队列
接受消息----put()
判断队列是否为空-----队列名.enpty()
读取------队列名.get()
举例:#进程之间的通信

from multiprocessing import Process,Queue

def write(q):

for i in range(5):

q.put(i)

print(“添加的元素是:”,i)

time.sleep(0.1)

print(“队列满了”)

def read(q):

while 1:

if not q.empty():

u=q.get(True)

print(u)

time.sleep(0.1)

else:

print(“队列空了”)

break

if name == ‘main’:

q=Queue(5)

t=Process(target=write,args=(q,))

t1=Process(target=read,args=(q,))

t.start()

t.join()

t1.start()

t1.join()

进程池—Pool()
作用:快速批量的创建进程
举例:
from multiprocessing import Pool
def func(i):
print("%d开始执行,%d进程号"%(i,os.getpid()))
time.sleep(1)

if name == ‘main’:
# print(“开始”)
p=Pool(3)
for i in range(10):
p.apply_async(func,(i,))
p.close()
p.join() #子线程结束以后再执行主线程
p.terminate() #立即结束子线程
time.sleep(0.1)
print(“结束”)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值