with关键字

with 关键字

with关键字为我们提供了一种优雅的方式来处理文件操作、数据库连接等需要明确释放资源的场景

with是python中的一个关键字,用于上下文管理协议(context Mangement protocol),它简化了资源管理代码,特别是那些需要明确释放或者清理的资源(如文件,网络连接,数据库连接等)

传统资源管理的问题

file = open('example.txt', 'r')
try:
    content = file.read()
    # 处理文件内容
finally:
    file.close()
  • 容易忘记关闭资源:如果没有try-finally块,可能会忘记close()
  • 代码冗长
  • 异常处理复杂

with语句的优势

with语句通过上下文管理协议解决了这些问题:

  • 自动资源释放:确保资源在使用后正确关闭
  • 代码简洁
  • 异常安全:即使在代码块中发生异常,资源也会被正确释放
  • 可读性强

with语句的基本语法

基本形式如下:

with expression [as variable]:
    # 代码块
  • expression 返回一个支持上下文管理协议的对象
  • as variable 是可选的,用于将表达式结果赋值给变量
  • 代码块执行完毕后,自动调用清理方法

实际应用场景

  1. 文件操作

    # 同时打开多个文件
    with open('input.txt', 'r') as infile, open('output.txt', 'w') as outfile:
        content = infile.read()
        outfile.write(content.upper())
    
  2. 数据库连接

    import sqlite3
    
    with sqlite3.connect('database.db') as conn:
        cursor = conn.cursor()
        cursor.execute('SELECT * FROM users')
        results = cursor.fetchall()
    # 连接自动关闭
    
  3. 线程锁

    import threading
    
    lock = threading.Lock()
    
    with lock:
        # 临界区代码
        print("这段代码是线程安全的")
    

面向对象

类(Class)与对象(Object)

类(class)是用来描述具有相同属性(Attribute)和方法(Method)对象的集合。对象(Object)是类(Class)的具体实例。

  • 属性(Attribute):类里面用于描述所有对象共同特征的变量和数据。
  • 方法(Method):类里面的函数,用量区别外面的函数,用来实现某些功能。
# 创建一个学生类
class Student:
    # 定义学生属性,初始化方法  构造方法
    def __init__(self, name, score):
        self.name = name
        self.score = score

    # 定义打印学生信息的方法
    def show(self):
        print("Name: {}. Score: {}".format(self.name, self.score))

创建具体的学生对象(Object):

student1 = Student("john",100)

当我们输入上述代码时,Python会自动调用默认的__init__初始构造函数来生成具体的对象。关键字self是个非常重要的参数,代表创建的对象本身。

类变量(Class variables)与实例变量(Instance variables)

# 创建一个学生类
class Student:
    # number属于类变量,不属于某个具体的学生实例
    number = 0
    
    # 定义学生属性,初始化方法
    # name和score属于实例变量
    def __init__(self, name, score):
        self.name = name
        self.score = score
        Student.number = Student.number + 1
    
    # 定义打印学生信息的方法
    def show(self):
        print("Name: {}. Score: {}".format(self.name, self.score))

# 实例化,创建对象
student1 = Student("John", 100)
student2 = Student("Lucy", 99)

print(Student.number)  # 打印2
print(student1.__class__.number) # 打印2

类变量与实例变量的区别:

  • 类变量:类变量在整个实例化的对象中是公用的,类变量定义在类中且在函数体之外。访问或调用类变量的正确方式是类名.变量名或者self.__class__.变量名self.__class__自动返回每个对象的类名。
  • 实例变量:定义在方法中的变量,属于某个具体的对象,访问或调用实例变量的正确方式是对象名.变量名或者self.变量名.

类的私有属性(private attribute)和私有方法(private method)

类里面的私有属性和私有方法以双下划线__开头。私有属性或方法不能在类的外部被使用或直接访问

# 创建一个学生类
class Student:

    # 定义学生属性,初始化方法
    # name和score属于实例变量, 其中__score属于私有变量
    def __init__(self, name, score):
        self.name = name
        self.__score = score
    
    # 定义打印学生信息的方法
    def show(self):
        print("Name: {}. Score: {}".format(self.name, self.__score))

# 实例化,创建对象
student1 = Student("John", 100)

student1.show()  # 打印 Name: John, Score: 100
student1.__score  # 打印出错,该属性不能从外部访问。

@property的用法与神奇之处

在上述案例中用户不能用student1.__score方式访问学生分数,然而用户也就知道了__score是个私有变量。我们有没有一种方法让用户通过student1.score来访问学生分数而继续保持__score私有变量的属性呢?这时我们就可以借助python的@property装饰器了

# 创建一个学生类
class Student:

    # 定义学生属性,初始化方法
    # name和score属于实例变量, 其中score属于私有变量
    def __init__(self, name, score):
        self.name = name
        self.__score = score
    
    # 利用property装饰器把函数伪装成属性
    @property
    def score(self):
        print("Name: {}. Score: {}".format(self.name, self.__score))

# 实例化,创建对象

student1 = Student("John", 100)

student1.score  # 打印 Name: John. Score: 100

注意:一旦给函数加上一个装饰器@property 调用函数的时候不用加括号就可以直接调用函数了

静态变量和静态方法

静态变量和静态方法都属于类的静态成员,它们与普通的实例变量和实例方法不同,静态变量和静态方法只属于定义它们的类,而不属于某一个实例对象

把类中的方法声明为静态方法,可以使用@staticmethod装饰器

# 创建一个学生类
class Student:
    # number属于类变量,定义在方法外,不属于具体实例
    number = 0
    # 定义学生属性,初始化方法
    # name和score属于实例变量,定义在方法里
    def __init__(self, name, score):
        self.name = name
        self.score = score
       
        Student.number = number + 1
        
    # 定义打印学生信息的方法
    def show(self):
        print("Name: {}. Score: {}".format(self.name, self.score))
    
    # 静态方法无法使用cls和self参数访问类或实例的变量
    @staticmethod
    def func1():
        print("this is static function!")

静态变量和静态方法都可以通过类名和实例对象进行访问,同时不像类方法和实例方法,静态方法无法接收clsself作为第一个参数。

posted @ 2025-10-19 18:18  小郑[努力版]  阅读(6)  评论(0)    收藏  举报