当前位置: 首页 > article >正文

Python小白学习教程从入门到入坑------第二十七课 魔法方法(语法进阶)

目录

一、什么是魔法方法?

二、常见的魔法方法

三、魔法方法&魔法属性

3.1 __doc__()

3.2 __module__()

3.3 __class__()

3.4 __str__()

3.5 __del__() 


一、什么是魔法方法?

在Python中,__xx__() 的函数叫做魔法方法,指的是具有特殊功能的函数

在Python中,魔法方法(Magic Methods)也被称为双下方法(Dunder Methods),因为它们通常以两个下划线(__)开始和结束

这些方法是Python内置的特殊方法,用于定义对象的内置操作的行为

通过重写这些魔法方法,可以自定义对象的行为,使它们表现得像Python的内置类型一样

二、常见的魔法方法

1. __new__(): 在内存中为对象分配空间并返回对象的引用

2. __init__(): 初始化对象或给属性赋值(构造函数)

3. __doc__(): 类的描述信息

4. __module__(): 表示当前操作对象所在模块

5. __class__(): 表示当前操作对象所在的类

6. __str__(): 对象的描述信息

7. __del__(): 删除对象(析构函数)

8. __cal__(): 使一个实例对象成为一个可调用对象

9. __dict__() : 返回对象具有的属性和方法

三、魔法方法&魔法属性

3.1 __doc__()

__doc__:类、函数的描述信息

eg:

class Person(object):
    """人类——类的描述信息"""    # 只能使用多行注释,单行注释无效
    pass
print(Person.__doc__)
# 人类——类的描述信息

3.2 __module__()

__module__():表述当前操作对象所在的模块

这个属性在动态导入模块、调试、或者当你需要基于对象的来源模块做一些处理时非常有用

例如,你可以通过检查 __module__ 属性来判断一个函数是从哪个模块导入的,或者是在当前脚本中定义的

下面是一个简单的例子来说明 __module__ 的用法:

# 假设这是在一个名为 mymodule.py 的文件中

def my_function():
    pass

class MyClass:
    pass

# 在这个文件中,我们可以打印这些对象的 __module__ 属性
print(my_function.__module__)  # 输出: mymodule
print(MyClass.__module__)      # 输出: mymodule

如果你从另一个脚本中导入 mymodule 并访问这些函数或类,它们的 __module__ 属性仍然会指向定义它们的原始模块名 mymodule

# 在另一个脚本中
import mymodule

print(mymodule.my_function.__module__)  # 输出: mymodule
print(mymodule.MyClass.__module__)      # 输出: mymodule

如果这个函数或类是在当前脚本中定义的(即不是从模块中导入的),那么它们的 __module__ 属性会是 '__main__'

# 在当前脚本中
def another_function():
    pass

print(another_function.__module__)  # 输出: '__main__'

3.3 __class__()

__class__:表示当前操作对象所在的类

接下来我们举一个例子解释说明一下:

新建一个py文件,pytest2.py

class B:
    def funa(self):
        print("哈哈哈")

在另一个py文件中调用,选择在py10.py文件中调用,如下:

import pytest2
b = pytest2.B()
print(b)
b.funa()
print(b.__module__)   # 输出模块
print(b.__class__)    # 输出类

# 输出内容:
# <pytest2.B object at 0x00000275E478FA08>
# 哈哈哈
# pytest2
# <class 'pytest2.B'>

3.4 __str__()

__str__():对象的描述信息

如果类中定义了此方法,那么在打印对象时,默认输出该方法的返回值,也就是打印方法中的return 的数据

注意:__str__() 必须返回一个字符串

在Python中,__str__() 是一个特殊方法(也称为魔术方法或双下方法),用于定义一个对象的“非正式”或可打印的字符串表示

当你尝试将一个对象转换为字符串(例如,使用 print() 函数或 str() 函数)时,Python 会自动调用该对象的 __str__() 方法

下面是一个简单的例子来解释 __str__() 方法的用法:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        # 返回一个字符串,描述了Person对象的属性
        return f"Person(name={self.name}, age={self.age})"

# 创建一个Person类的实例
person1 = Person("Alice", 30)

# 当我们尝试打印person1对象时,Python会调用它的__str__()方法
print(person1)  # 输出: Person(name=Alice, age=30)

# 我们也可以直接使用str()函数来调用__str__()方法
person_str = str(person1)
print(person_str)  # 输出: Person(name=Alice, age=30)

在这个例子中,我们定义了一个名为 Person 的类,它有两个属性:name 和 age。我们还定义了一个 __str__() 方法,该方法返回一个字符串,描述了 Person 对象的这两个属性

当我们创建一个 Person 类的实例 person1 并尝试打印它时,Python 会自动调用 person1 的 __str__() 方法,并打印该方法返回的字符串

__str__() 方法的主要用途是提供一个清晰、易读的字符串表示,以便在调试、日志记录或向用户显示对象信息时使用

3.5 __del__() 

__del__() : 析构函数,在程序结束时会调用,或者在删除某个对象的时候也会被调用

这个方法的主要目的是允许对象在销毁前执行一些清理操作,比如关闭文件、释放资源等

然而,需要注意的是,__del__() 方法的调用并不是确定的,也不是立即发生的

Python的垃圾回收机制通过引用计数和循环检测来管理内存,当对象的引用计数降为零时,对象可能立即被销毁,也可能稍后被销毁,具体取决于垃圾回收器的运行时机

此外,__del__() 方法中的异常通常会被忽略,这意味着如果在 __del__() 方法中发生了异常,它不会被传播到外部。这可能会使得调试变得困难,因为异常不会显示在程序的正常错误处理流程中。

下面是一个简单的例子来解释 __del__() 方法的用法:

class MyClass:
    def __init__(self, name):
        self.name = name
        print(f"{self.name} has been created.")

    def __del__(self):
        print(f"{self.name} is being destroyed.")

# 创建一个MyClass类的实例
obj = MyClass("MyObject")

# 此时,obj的引用计数仍然大于0,所以__del__()方法不会被调用
# 我们可以显式地删除obj来触发__del__()方法(尽管这通常不是必要的,因为Python的垃圾回收器会自动处理)
del obj  # 输出: MyObject is being destroyed.

# 然而,如果对象是通过其他方式被引用的(比如在一个列表中),那么仅仅删除一个引用并不会触发__del__()方法
# 直到所有引用都被删除,或者程序结束并且垃圾回收器运行,对象才会被销毁

在上面的例子中,当 obj 被创建时,__init__() 方法被调用,打印出创建信息

然后,当我们使用 del 语句删除 obj 时,__del__() 方法被调用,打印出销毁信息

但是,通常不建议在 __del__() 方法中做太多重要的清理工作,因为它们的执行是不确定的

相反,建议使用上下文管理器(通过实现 __enter__() 和 __exit__() 方法)或显式地关闭资源(比如使用 with 语句来管理文件或网络连接)。这些机制提供了更可靠和可预测的资源管理方式

今天的分享就到这里了,希望本文能够对大家有帮助~


http://www.kler.cn/a/382029.html

相关文章:

  • 医疗大模型威胁攻击下的医院AI安全:挑战与应对策略
  • 绕组识别标签规范
  • Android基于Path的addRoundRect,Canvas剪切clipPath简洁的圆角矩形实现,Kotlin(1)
  • git命令恢复/还原某个文件、删除远程仓库中的文件
  • 【pycharm】远程服务器之后如何打开终端
  • 问题解决:发现Excel中的部分内容有问题。是否让我们尽量尝试恢复? 如果您信任此工作簿的源,请单击“是”。
  • 【数据结构】堆:TOK问题
  • Spring Boot 与 Vue 共筑二手书籍交易卓越平台
  • 可选链操作符(Optional Chaining)
  • unity3d——关于GetComponent<T>()
  • 解决Knife4j 接口界面UI中文乱码问题
  • 扩展卡尔曼滤波(EKF)的限制
  • 西南科技大学C++实验作业3——容器使用和文件输入输出流
  • 实现数传数据转网口(以太网)和遥控器SBUS信号转串口的功能
  • leetcode 75.颜色分类
  • Python的struct打包通讯数据头文件
  • 杨辉三角——c语言
  • 浏览器内核版本更新:Chrome 130✔
  • 【MySQL】函数
  • 网络安全求职指南_看完这篇就足够了~
  • c++设计模式demo
  • 【Linux】Linux安全与密钥登录指南
  • 工作管理实战指南:利用Jira、Confluence等Atlassian工具打破信息孤岛,增强团队协作【含免费指南】
  • 算法学习(十)—— 字符串
  • Oracle 第15章:安全性管理
  • 基于python主观题自动阅卷系统毕业设计项目