赞
踩
在Python编程的进阶道路上,理解变量作用域、垃圾回收、拷贝机制与异常处理至关重要。本文将深入探讨这些核心概念,助你编写更健壮、高效的代码。从变量作用域到内存管理,再到数据拷贝与异常捕获,让我们一同揭开Python编程的深层奥秘。
内置命名空间 — python解释器范围下
全局命名空间 — py文件下
局部命名空间 — 函数或类下
内置作用域 校长 全局作用域 年级主任 嵌套作用域 班主任 局部作用域 讲师 # 全局作用域下的变量:全局变量 a = 10 def func(): # 嵌套作用域下的变量 c = 30 def func1(): # 局部作用域下的变量:局部变量 b = 20 def、class、lambda 是可以引入新作用域的
LEGB:作用域的查询顺序(就近原则) 内置作用域 built-in B 全局作用域 Global G 嵌套作用域 Enclosed E 局部作用域 Local L 局部-->嵌套-->全局-->内置 # 全局作用域下的变量:全局变量 a = 10 def func(): # 嵌套作用域下的变量 a = 30 def func1(): # 局部作用域下的变量:局部变量 a = 20 print(a) func1() func()
a = 10
def func():
# 修改全局变量的值--》不可变数据类型
# global 要修改的全局变量的变量名
# 换行对变量进行重新赋值
global a
a = 20
print(a)
func()
print(a)
def outer():
a = 10
def inner():
# 修改嵌套作用域下的变量 nonlocal
# nonlocal 要修改的嵌套作用域下的变量名
# 换行给变量重新赋值
nonlocal a
a += 1
print(a)
inner()
print(a)
outer()
每一个对象会维护一个ob_ref表,表中存放当前对象的被引用次数; 当对象的被引用次数为0,当前对象会被作为垃圾进行收回 import sys # 引用计数 # 获取对象的被引用次数 print(sys.getrefcount(1)) # 引用计数+1 a = 1 b = a lst = [1,2,3,4] # 引用计数-1 b = 2 del a print(sys.getrefcount(1))
跟其名称一样,该算法在进行垃圾回收时分成了两步,分别是:
- A)标记阶段,遍历所有的对象,如果是可达的(reachable),也就是还有对象引用它,那么就标记该对象为可达;
- B)清除阶段,再次遍历对象,如果发现某个对象没有标记为可达,则就将其回收。
缺陷:在执行标记清除过程中,会将其他正在执行的程序进行终止。会使得资源利用率极低
它将内存中的对象按生存期划分为几个不同的"代",每次只对某一代进行回收,
优点:减少垃圾回收的次数,提高垃圾回收的效率。
它将内存中的对象分为三种:新生代、老年代和永久代。
新生代只包括新创建的对象;
老年代是存放比较“老”的对象,也就是存活比较久的对象;
永久代则存放三种物件:模块、类和常量。
# is和 ==
# a == b:判断a和b的值是否相等;如果相等则返回True,否则返回False
# a is b:判断a和b是否是同一个数据;
# 获取对象的内容地址 id(数据)
# 指向关系:整型、浮点型、字符串、元组 (不可变)
a = {"name":"张三"}
b = {"name":"张三"}
print(id(a))
print(id(b))
print(a == b)
print(a is b)
import copy # 拷贝模块 copy # 浅拷贝 需要使用copy模块中copy方法 # 结论:浅拷贝只拷贝第一层,深层次的数据改变都会影响其他. # 拷贝不可变数据类型的数据--》不可变数据类型永远指向关系 a = (1,2,3) b = copy.copy(a) print(id(a),id(b)) print(a is b) # 拷贝可变数据类型的数据 list1 = [1,2,3,[4,5,6]] list2 = copy.copy(list1) # 获取整个数据的id,浅拷贝后的数据id不同 print(id(list1),id(list2)) print(list1 is list2) # 查询拷贝前后深层次数据是否是同一个 print(id(list1[3]),id(list2[3])) print(list1[3] is list2[3]) # 修改原数据中浅层数据,拷贝后的数据不会发生变化 list1.append(7) print(list1) print(list2) # 修改原数据中深层数据,拷贝后的数据会随之发生变化 list1[3].append(8) print(list1) print(list2)
import copy # 深拷贝 需要使用copy模块deepcopy # 结论:深拷贝是完全拷贝,数据变化只影响自己本身 # 拷贝不可变数据类型--》不可变数据类型永远都是指向关系 a = ("hello",) b = copy.deepcopy(a) print(id(a),id(b)) print(a is b) # 拷贝可变数据类型 list1 = [1,2,3,[4,5,6]] list2 = copy.deepcopy(list1) # 获取整个数据的id,拷贝后的数据id不同 print(id(list1),id(list2)) print(list1 is list2) # 查询拷贝前后深层次数据是同一个 print(id(list1[3]),id(list2[3])) print(list1[3] is list2[3]) # 对原数据的浅层数据进行操作,拷贝后的数据不会发生变化 list1.append(7) print(list1) print(list2) # 对原数据的深层数据进行操作,拷贝后数据不会发生变化 list1[3].append(8) print(list1) print(list2)
浅拷贝:只拷贝第一层数据,深层数据还是指向关系
深拷贝:完全拷贝,拷贝前后的数据没有关系
# 简单异常处理
# try:
# 存放可能会出现问题的代码
# except 异常类型:
# 如果真的出现这个异常,则执行except中的代码
list1 = [1,2,3]
try:
print(list1[20])
except IndexError:
print("好好数数你的索引!!!!")
# try:
# 存放可能会出现问题的代码
# except 异常类型:
# 如果真的出现这个异常,则执行except中的代码
# except 异常类型:
# 如果真的出现这个异常,则执行except中的代码
list1 = [1,2,3]
try:
print(list2[20])
except IndexError:
print("好好数数你的索引!!!!")
except NameError:
print("瞧瞧你的变量名~")
# try:
# 存放可能会出现问题的代码
# except (异常类型1,异常类型2):
# 如果真的出现这个异常,则执行except中的代码
list1 = [1,2,3]
try:
print(list1[20])
except (IndexError,NameError):
print("好好看看你的变量")
# try:
# 存放可能会出现问题的代码
# except:
# 如果真的出现异常,则执行except中的代码
list1 = [1,2,3]
try:
list1.add(4)
print(list2[20])
except:
print("好好看看你的变量")
# 获取错误信息
# 异常类型 as 变量:将出现当前异常的错误信息赋值给变量
list1 = [1,2,3]
try:
print(list1[20])
except IndexError as e:
print(e)
# 获取错误信息
# 异常类型 as 变量:将出现当前异常的错误信息赋值给变量
list1 = [1,2,3]
try:
print(list1[20])
except (IndexError,NameError) as e:
print(e)
# Exception:所有常规异常的基类,包含所有的常规异常
# try:
# 存放可能会出现问题的代码
# except Exception as e:
# print(e)
# 如果真的出现异常,则执行except中的代码;e接收所有的错误信息
list1 = [1,2,3]
try:
list1.add(4)
print(list1[20])
except Exception as e:
print(e)
# try:
# 可能会出现问题的代码
# except Exception as e:
# 如果真的出现异常则执行except中的代码块
# else:
# 如果代码没有出现异常则执行else中的代码块
list1 = [1,2,3]
try:
print(list1[20])
except Exception as e:
print(e)
else:
print("嘿嘿嘿嘿嘿嘿")
# finally-->可以只与try搭配使用 # try: # 可能会出现问题的代码 # except Exception as e: # 如果代码出现问题则执行except中的代码块 # else: # 如果代码没有问题则执行else中的代码块 # finally: # 无论代码是否出现问题最终都会执行finally中的代码块 list1 = [1,2,3] try: print(list1[2]) except Exception as e: print(e) print("这是except中的代码") else: print("这是else中的代码") finally: print("这是finally中的代码")
class MyCls: def __init__(self,s): self.s = s def a(self,a,b): try: return a/b except Exception as e: if self.s == True: print(e) else: # 将原本需要抛出的异常进行抛出 # raise 异常类型 -->在程序中raise 后面的异常类型可以不指定 raise my = MyCls(True) print(my.a(10,0))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。