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


相关文章
|
1月前
|
数据库连接 Python
Python中的异常处理除了Try语句,你还会啥?
Python中的异常处理除了Try语句,你还会啥?
37 1
|
29天前
|
Python
|
6天前
|
Python
Python编程中的异常处理:理解与实践
【9月更文挑战第14天】在编码的世界里,错误是不可避免的。它们就像路上的绊脚石,让我们的程序跌跌撞撞。但是,如果我们能够预见并优雅地处理这些错误,我们的程序就能像芭蕾舞者一样,即使在跌倒的边缘,也能轻盈地起舞。本文将带你深入了解Python中的异常处理机制,让你的代码在面对意外时,依然能保持优雅和从容。
143 73
|
23天前
|
Python
Python变量的作用域_参数类型_传递过程内存分析
理解Python中的变量作用域、参数类型和参数传递过程,对于编写高效和健壮的代码至关重要。正确的应用这些概念,有助于避免程序中的错误和内存泄漏。通过实践和经验积累,可以更好地理解Python的内存模型,并编写出更优质的代码。
15 2
|
30天前
|
IDE 测试技术 开发工具
Python接口自动化测试框架(基础篇)-- 讨厌的异常处理
本文详细讨论了Python中的异常处理机制,包括异常捕获、异常抛出、自定义异常、环境清理,以及使用上下文管理器确保资源正确释放,最后还提到了Python的标准异常类。
14 1
|
1月前
|
存储 数据采集 人工智能
一:《Python基础语法汇总》— 变量与数据类型
【8月更文挑战第15天】本篇文章详细讲述了关于变量的命名规范,id()函数及Python的数据类型与强制转换
17 2
|
1月前
|
开发者 Python
Python中的异常处理机制及其实践
【8月更文挑战第12天】Python的异常处理机制通过`try`和`except`结构显著提高了程序的稳定性和可靠性。在`try`块中执行可能引发异常的代码,如果发生异常,控制权将转移到与该异常类型匹配的`except`块。此外,还可以通过`else`处理无异常的情况,以及使用`finally`确保某些代码无论如何都会被执行,非常适合进行清理工作。这种机制允许开发者精确地捕捉和管理异常,从而提升程序的健壮性和可维护性。同时,Python还支持定义自定义异常,进一步增强了错误处理的灵活性。
39 4
|
22天前
|
PHP 开发者 UED
PHP中的异常处理:从基础到高级探索Python中的列表推导式:简洁而强大的工具
【8月更文挑战第30天】在PHP编程的世界中,异常处理是确保代码健壮性和可靠性的关键机制。本文将引导您了解PHP异常处理的基本概念,并通过实际示例展示如何有效地捕获和处理异常。我们将一起探索try-catch结构、自定义异常类以及高级异常处理技术,让您的PHP代码更加稳固和易于维护。
|
23天前
|
Python
|
24天前
|
算法 Java 开发者
Python垃圾回收机制
Python垃圾回收机制