Python进阶之旅:深入理解变量作用域、垃圾回收、拷贝机制与异常处理

简介: Python进阶之旅:深入理解变量作用域、垃圾回收、拷贝机制与异常处理

前言

    在Python编程的进阶道路上,理解变量作用域、垃圾回收、拷贝机制与异常处理至关重要。本文将深入探讨这些核心概念,助你编写更健壮、高效的代码。从变量作用域到内存管理,再到数据拷贝与异常捕获,让我们一同揭开Python编程的深层奥秘。


一、变量的作用域

1.命名空间

内置命名空间 — python解释器范围下

全局命名空间 — py文件下

局部命名空间 — 函数或类下

2.作用域

内置作用域    校长 
全局作用域    年级主任
嵌套作用域    班主任
局部作用域    讲师
# 全局作用域下的变量:全局变量
a = 10
def func():
    # 嵌套作用域下的变量
    c = 30
    def func1():
        # 局部作用域下的变量:局部变量
        b = 20
def、class、lambda 是可以引入新作用域的

3.LEGB法则

LEGB:作用域的查询顺序(就近原则)
内置作用域     built-in    B
全局作用域     Global      G
嵌套作用域     Enclosed    E
局部作用域     Local       L
局部-->嵌套-->全局-->内置
# 全局作用域下的变量:全局变量
a = 10
def func():
    # 嵌套作用域下的变量
    a = 30
    def func1():
        # 局部作用域下的变量:局部变量
        a = 20
        print(a)
    func1()
func()

4.修改全局变量

a = 10
def func():
    # 修改全局变量的值--》不可变数据类型
    # global 要修改的全局变量的变量名
    # 换行对变量进行重新赋值
    global a
    a = 20
    print(a)
func()
print(a)

5.修改嵌套作用域下的变量

def outer():
    a = 10
    def inner():
        # 修改嵌套作用域下的变量  nonlocal
        # nonlocal 要修改的嵌套作用域下的变量名
        # 换行给变量重新赋值
        nonlocal a
        a += 1
        print(a)
    inner()
    print(a)
outer()

二、python垃圾回收机制

1. 引用计数

每一个对象会维护一个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))

2. 标记清除

跟其名称一样,该算法在进行垃圾回收时分成了两步,分别是:
- A)标记阶段,遍历所有的对象,如果是可达的(reachable),也就是还有对象引用它,那么就标记该对象为可达;
- B)清除阶段,再次遍历对象,如果发现某个对象没有标记为可达,则就将其回收。
缺陷:在执行标记清除过程中,会将其他正在执行的程序进行终止。会使得资源利用率极低

3.分代回收

它将内存中的对象按生存期划分为几个不同的"代",每次只对某一代进行回收,
优点:减少垃圾回收的次数,提高垃圾回收的效率。
它将内存中的对象分为三种:新生代、老年代和永久代。
  新生代只包括新创建的对象;
  老年代是存放比较“老”的对象,也就是存活比较久的对象;
  永久代则存放三种物件:模块、类和常量。

三、深浅拷贝

1. is 和 ==

# 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)

2.浅拷贝

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)

3.深拷贝

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)

4.深浅拷贝的区别

浅拷贝:只拷贝第一层数据,深层数据还是指向关系

深拷贝:完全拷贝,拷贝前后的数据没有关系


四、异常处理

1.简单异常处理

# 简单异常处理
# try:
#     存放可能会出现问题的代码
# except 异常类型:
#     如果真的出现这个异常,则执行except中的代码
list1 = [1,2,3]
try:
    print(list1[20])
except IndexError:
    print("好好数数你的索引!!!!")

2.处理多种异常

2.1 第一种方式

# try:
#     存放可能会出现问题的代码
# except 异常类型:
#     如果真的出现这个异常,则执行except中的代码
# except 异常类型:
#     如果真的出现这个异常,则执行except中的代码
list1 = [1,2,3]
try:
    print(list2[20])
except IndexError:
    print("好好数数你的索引!!!!")
except NameError:
    print("瞧瞧你的变量名~")

2.2 第二种方法

# try:
#     存放可能会出现问题的代码
# except (异常类型1,异常类型2):
#     如果真的出现这个异常,则执行except中的代码
list1 = [1,2,3]
try:
    print(list1[20])
except (IndexError,NameError):
    print("好好看看你的变量")

2.3 第三种方式

# try:
#     存放可能会出现问题的代码
# except:
#     如果真的出现异常,则执行except中的代码
list1 = [1,2,3]
try:
    list1.add(4)
    print(list2[20])
except:
    print("好好看看你的变量")

3.获取异常信息

3.1 单个异常

# 获取错误信息
# 异常类型 as 变量:将出现当前异常的错误信息赋值给变量
list1 = [1,2,3]
try:
    print(list1[20])
except IndexError as e:
    print(e)

3.2 多个异常

# 获取错误信息
# 异常类型 as 变量:将出现当前异常的错误信息赋值给变量
list1 = [1,2,3]
try:
    print(list1[20])
except (IndexError,NameError) as e:
    print(e)

4.万能异常处理

# 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)

5.else

# try:
#     可能会出现问题的代码
# except Exception as e:
#     如果真的出现异常则执行except中的代码块
# else:
#     如果代码没有出现异常则执行else中的代码块
list1 = [1,2,3]
try:
    print(list1[20])
except Exception as e:
    print(e)
else:
    print("嘿嘿嘿嘿嘿嘿")

6.finally

# 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中的代码")

7.自定义异常

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))


相关文章
|
2天前
|
安全 Python 容器
|
2天前
|
Python
Python中解包到单独的变量对于字典
【6月更文挑战第20天】
17 11
|
2天前
|
Python
|
3天前
|
开发者 Python
在Python中,异常处理通过`try`、`except`、`else`和`finally`关键字进行
【6月更文挑战第26天】在Python中,异常处理通过`try`、`except`、`else`和`finally`关键字进行。基本结构包括尝试执行可能抛出异常的代码,然后指定`except`来捕获特定或任何类型的异常。`else`块在`try`无异常时执行,`finally`块确保无论是否发生异常都会执行,例如用于清理。可以使用`raise`重新抛出异常,而自定义异常则允许创建特定的错误类。这种机制增强了代码的健壮性。
19 7
|
3天前
|
开发者 Python
Python进阶:深入剖析闭包与装饰器的应用与技巧
Python进阶:深入剖析闭包与装饰器的应用与技巧
|
3天前
|
分布式计算 算法 Python
Python函数进阶:四大高阶函数、匿名函数、枚举、拉链与递归详解
Python函数进阶:四大高阶函数、匿名函数、枚举、拉链与递归详解
|
3天前
|
Python
Python面向对象进阶:深入解析面向对象三要素——封装、继承与多态
Python面向对象进阶:深入解析面向对象三要素——封装、继承与多态
|
3天前
|
Python
Python中解包到嵌套变量
【6月更文挑战第19天】
5 2
|
3天前
|
存储 数据处理 Python
Python中解包到变量并忽略某些元素
【6月更文挑战第19天】
7 2
|
1天前
|
机器学习/深度学习 人工智能 程序员
探索Python宝库:从基础到技能的干货知识(数据类型与变量+ 条件与循环+函数与模块+文件+异常+OOP)
探索Python宝库:从基础到技能的干货知识(数据类型与变量+ 条件与循环+函数与模块+文件+异常+OOP)
2 0