引言
python小程序之魔法方法(__init__方法、__str__方法、__del__方法)
文章目录
- 引言
- 一、__init__方法
- 1.1 题目
- 1.2 代码
- 1.3 代码解释
- 1.3.1 逐行注释
- 1.3.2 代码执行过程
 
 
- 二、__str__方法
- 2.1 题目
- 2.2 代码
- 2.3 代码解释
 
- 三、__del__方法
- 3.1 题目
- 3.2 代码
- 3.3 代码解释
 
- 四、思考
- 4.1 __init__方法
- 4.1.1 语法
- 4.1.2 参数
- 4.1.3 用途
- 4.1.4 示例
- 4.1.5 注意事项
 
- 4.2 __str__方法
- 4.2.1 一个包含 `__str__` 方法的简单类的例子
- 4.2.2 `__str__`方法的一些规则
 
- 4.3 __del__方法
- 4.3.1 为什么“代码执行结束”在del方法前打印
 
 
一、__init__方法
1.1 题目
如何使用__init__方法
1.2 代码
class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def show_info(self):
        print(f'小猫的名字是:{self.name},小猫的年龄是:{self.age}岁')
blue_cat = Cat('小蓝', '3')
print(blue_cat.name)
blue_cat.show_info()
pink_cat = Cat('大粉', 4)
print(pink_cat.name)
pink_cat.show_info()
输出结果:
 
1.3 代码解释
1.3.1 逐行注释
这段代码定义了一个名为 Cat 的类,该类有两个属性:name 和 age,以及一个名为 show_info 的方法
class Cat:  # 定义一个名为Cat的类
    def __init__(self, name, age):  # 定义一个特殊方法__init__,它是类的构造器
        self.name = name  # 将传入的name参数赋值给对象的name属性
        self.age = age    # 将传入的age参数赋值给对象的age属性
    def show_info(self):  # 定义一个名为show_info的方法
        print(f'小猫的名字是:{self.name},小猫的年龄是:{self.age}岁')  # 打印出小猫的名字和年龄
# 使用Cat类创建一个名为blue_cat的实例,并传入'小蓝'和'3'作为参数
blue_cat = Cat('小蓝', '3')
print(blue_cat.name)  # 打印blue_cat实例的name属性,输出:小蓝
blue_cat.show_info()  # 调用blue_cat实例的show_info方法,输出:小猫的名字是:小蓝,小猫的年龄是:3岁
# 使用Cat类创建另一个名为pink_cat的实例,并传入'大粉'和4作为参数
pink_cat = Cat('大粉', 4)
print(pink_cat.name)  # 打印pink_cat实例的name属性,输出:大粉
pink_cat.show_info()  # 调用pink_cat实例的show_info方法,输出:小猫的名字是:大粉,小猫的年龄是:4岁
1.3.2 代码执行过程
- 定义了一个 Cat类,该类有一个构造器__init__和一个方法show_info
- 使用 Cat类创建了两个实例:blue_cat和pink_cat
- 在创建 blue_cat实例时,将字符串'小蓝'赋值给name属性,将字符串'3'赋值给age属性
- 在创建 pink_cat实例时,将字符串'大粉'赋值给name属性,将整数4赋值给age属性
- 通过 print函数打印出blue_cat和pink_cat实例的name属性
- 通过调用 show_info方法打印出blue_cat和pink_cat实例的详细信息,包括它们的名字和年龄
注意,在创建
blue_cat实例时,年龄是以字符串'3'传入的,而不是整数3。这不会影响show_info方法的输出,因为age属性进行数学运算,则应该确保它是一个整数
二、__str__方法
2.1 题目
如何使用__str__方法
2.2 代码
class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def show_info(self):
        print(f'小猫的名字是:{self.name},小猫的年龄是:{self.age}岁')
    def __str__(self):
        return f'小猫的名字是_str:{self.name},小猫的年龄是:{self.age}'
blue_cat = Cat('小蓝', '3')
print(blue_cat.name)
print(blue_cat)
pink_cat = Cat('大粉', 4)
print(pink_cat)
输出结果:
 
2.3 代码解释
这段代码定义了一个名为
Cat的类,该类有两个实例变量name和age,以及三个方法:__init__、show_info和__str__
class Cat:
这行代码定义了一个名为 Cat 的类。
    def __init__(self, name, age):
        self.name = name
        self.age = age
这是一个构造器方法 __init__,它在创建 Cat 类的新实例时被调用。它接收两个参数 name 和 age,并将它们分别赋值给实例变量 self.name 和 self.age
    def show_info(self):
        print(f'小猫的名字是:{self.name},小猫的年龄是:{self.age}岁')
这个方法 show_info 当被调用时,会打印出实例的 name 和 age
    def __str__(self):
        return f'小猫的名字是_str:{self.name},小猫的年龄是:{self.age}'
__str__ 方法定义了当类的实例被转换为字符串时应该返回的字符串。在这个例子中,它返回一个包含 name 和 age 的格式化字符串
 接下来,代码创建了两个 Cat 类的实例:
blue_cat = Cat('小蓝', '3')
这行代码创建了一个名为 blue_cat 的 Cat 实例,其名字为 '小蓝',年龄为字符串 '3'
print(blue_cat.name)
这行代码打印出 blue_cat 实例的 name 属性,输出结果为 '小蓝'
print(blue_cat)
这行代码打印出 blue_cat 实例的字符串表示。由于 Cat 类定义了 __str__ 方法,所以这里会调用 __str__ 方法,输出结果为 '小猫的名字是_str:小蓝,小猫的年龄是:3'
pink_cat = Cat('大粉', 4)
这行代码创建了一个名为 pink_cat 的 Cat 实例,其名字为 '大粉',年龄为整数 4。
print(pink_cat)
这行代码打印出 pink_cat 实例的字符串表示。同样,由于 Cat 类定义了 __str__ 方法,这里会调用 __str__ 方法,输出结果为 '小猫的名字是_str:大粉,小猫的年龄是:4'
注意,在创建
blue_cat实例时,年龄被传递为一个字符串'3',而不是整数3。这可能会导致在某些情况下类型不匹配的问题,例如,如果你想要在代码的其他部分对年龄进行算术运算。正确的做法是将年龄传递为整数。在创建pink_cat实例时,年龄正确地被传递为整数4
三、__del__方法
3.1 题目
如何使用__del__方法
3.2 代码
class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print(f'我是{self.name},我被调用了')
    def show_info(self):
        print(f'小猫的名字是:{self.name},小猫的年龄是:{self.age}岁')
    def __str__(self):
        return f'小猫的名字是_str:{self.name},小猫的年龄是:{self.age}'
    def __del__(self):
        print(f'{self.name}没了,给他处理后事')
blue_cat = Cat('小蓝', '3')
print('代码运行结束')
输出结果:
 
3.3 代码解释
这段代码定义了一个名为
Cat的类,并创建了一个Cat类的实例blue_cat
- 定义 Cat类:-  __init__方法:这是一个特殊的方法,每当创建Cat类的新实例时,Python会自动调用它。这个方法接收两个参数name和age,并将它们分别赋值给实例变量self.name和self.age。之后,它打印一条消息,表明实例已经被创建,并包含了实例的名字
-  show_info方法:这个方法打印出Cat实例的信息,包括名字和年龄
-  __str__方法:这是一个特殊的方法,它定义了当调用str()函数或使用print()函数打印Cat实例时的字符串表示。这个方法返回一个格式化的字符串,包含了实例的名字和年龄
-  __del__方法:这是一个特殊的方法,它是类的析构器。当Cat实例被销毁(例如,当它的引用计数降到零)时,Python会调用这个方法。在这个方法中,打印了一条消息,表明实例即将被销毁,并包含了实例的名字
 
-  
- 创建 Cat类的实例blue_cat:- blue_cat = Cat('小蓝', '3'):这行代码创建了一个名为- blue_cat的- Cat类实例,并传递了字符串- '小蓝'和字符串- '3'作为- name和- age参数。由于- __init__方法中有一条打印语句,因此会立即看到输出 “我是小蓝,我被调用了”
 
- 打印一条消息表明代码运行结束: 
  - print('代码运行结束'):这行代码打印出 “代码运行结束”。这通常会在主程序执行完毕后立即发生
 
四、思考
4.1 __init__方法
在python中,
__init__方法是一个特殊的方法,它是一个类的构造器方法,也就是说,每当创建类的新实例时,python都会自动调用它。__init__方法的目的是初始化新创建的对象的状态
4.1.1 语法
class MyClass:
    def __init__(self, param1, param2, ..., paramN):
        # 初始化代码
4.1.2 参数
- self:代表类的实例本身,在创建实例时自动传递。通过- self,你可以设置对象属性或调用其他的方法
- param1, param2, ..., paramN:这些是除了- self之外传递给- __init__方法的参数。你可以根据需要传递任意数量的参数
4.1.3 用途
- 初始化对象的属性
- 执行任何创建对象时需要的设置
4.1.4 示例
class Cat:
    def __init__(self, name, age):
        self.name = name  # 初始化name属性
        self.age = age    # 初始化age属性
# 创建Cat类的实例
my_cat = Cat('Whiskers', 3)
print(my_cat.name)  # 输出: Whiskers
print(my_cat.age)   # 输出: 3
在这个例子中,__init__ 方法接受 name 和 age 两个参数,并将它们分别赋值给新创建的 Cat 实例的 name 和 age 属性
4.1.5 注意事项
- __init__方法不应该有返回值
- 如果你不显式定义 __init__方法,Python 会提供一个默认的构造器,它不接受任何参数,也不执行任何操作
- __init__方法不能直接调用,它是在创建类的实例时由Python解释器自动调用的。
 下面是一个没有定义- __init__方法的类的例子:
class MyClass:
    pass
obj = MyClass()  # 创建实例,没有 __init__ 方法被调用
在这个例子中,MyClass 没有定义 __init__ 方法,但是仍然可以创建它的实例。因为没有初始化逻辑,所以这个对象除了继承自 object 的属性外,没有其他属性
4.2 __str__方法
在python中,
__str__方法是一个特殊的方法,它定义了类的实例在被打印(使用print()函数)或被转换为字符串(使用str()函数)时的“官方”字符串表示形式。
当定义一个类时,如果想要控制打印这个类的实例时的输出,应该在类中定义一个__str__方法
4.2.1 一个包含 __str__ 方法的简单类的例子
 
class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f'小猫的名字是:{self.name}, 小猫的年龄是:{self.age}岁'
# 创建Cat类的实例
my_cat = Cat('Tom', 3)
# 打印实例,将调用__str__方法
print(my_cat)  # 输出: 小猫的名字是:Tom, 小猫的年龄是:3岁
在这个例子中,当使用 print(my_cat) 时,python会调用 my_cat 实例的 __str__ 方法来获取要打印的字符串。如果没有定义 __str__ 方法,print() 函数会调用 __repr__ 方法(如果定义了的话),否则会打印出对象的内存地址
4.2.2 __str__方法的一些规则
 
- __str__方法应该返回一个字符串
- 如果没有定义 __str__方法,类的实例在打印时将显示其内存地址
- __str__方法的目的是为了创建一个对用户友好的、可读性强的字符串表示形式
- __repr__方法通常用于创建一个明确的、尽可能不模糊的对象表示形式,通常可以用- eval(repr(obj))来重新创建对象,而- __str__不需要满足这个条件
 为了更好的实践,通常建议同时定义- __str__和- __repr__方法,其中- __str__提供更友好的输出,而- __repr__提供一个明确的对象表示
4.3 __del__方法
4.3.1 为什么“代码执行结束”在del方法前打印
在python中,print 调用的执行顺序遵循代码的顺序。以下是代码执行的步骤:
- 定义了 Cat类,其中包括__init__、show_info、__str__和__del__方法
- 创建 Cat类的实例blue_cat,这时__init__方法被调用,打印出 “我是小蓝,我被调用了”
- __init__方法执行完毕后,控制流返回到创建实例之后的代码行,即- print('代码运行结束'),这条语句被打印出来
- 程序接近尾声,由于没有更多的代码行,Python解释器开始进行垃圾回收,此时如果 blue_cat实例没有其他引用,__del__方法将被调用,打印出 “小蓝没了,给他处理后事”
 看到 “代码运行结束” 在__del__方法打印的 “小蓝没了,给他处理后事” 之前,是因为print('代码运行结束')这行代码在创建实例之后立即执行,而__del__方法则在解释器清理对象时执行,这通常发生在程序即将退出时
请注意,
__del__方法的调用时机是不确定的,它依赖于python的垃圾回收机制。在某些情况下,可能不会看到__del__方法打印的消息,特别是如果程序在__del__被调用之前就已经退出了。如果想在程序结束前确保看到__del__的输出,可以显式调用del blue_cat来删除实例



















