首页 > 技术文章 > python 3 基础之魔法方法(__new__、__init__、__mro__、__str__、__del__、__name__)

will-wu 2020-07-08 11:22 原文

1、魔法方法

  在python中使用__开头 并以__结尾的方法 称之为魔法方法,object的提供的魔法方法(继承于object)

  1.1、__init__   魔法方法

    构造方法(监听python使用其类创建对象完成,给这个对象设置属性)

    若一个类里面没写__init__方法,python会自动创建,但不执行任何操作

    若为了能在完成自己想要的功能,可以自己定义__init__方法

    所有一个类无论自己是否编写__init__方法,一定有此方法

    一般情况是有多个相同的数据时,避免数据冗余,使用__init__在方法内给对象的赋予属性,也叫构造方法

    创建对象后,python解释器默认调用__init__()方法,初始化对象,把此类的公共(此类都有的)属性默认添加给对象

class Dog(object):
    # 构造方法
    def __init__(self, new_name, new_age, new_colour="白色"):
        # 给对象的属性赋值,参数self代表的是一个依赖Dog类创建的对象
        self.name = new_name
        self.age = new_age
        self.colour = new_colour
    def info(self):
        print("名字:%s" % self.name)
        print("年龄:%d" % self.age)
        print("毛色:%s" % self.colour)
# 定义一个对象时给对象添加属性(其中,必须添加的参数为new_name, new_age,颜色是默认的)
wan = Dog('入魔',5)
wan.info()
=============================================================================
运行结果:
名字:入魔
年龄:5
毛色:白色

  1.2、__str__ 方法

    __str__方法会重写原来的方法,重写返回自定义的代码,一般用于程序员开发调试代码

class Hero(object):
    # 构造方法
    def __init__(self, name, hp, atk):
        # 设置属性的值
        self.name = name
        self.hp = hp
        self.atk = atk
    # 追踪对象属性信息变化
    def __str__(self):
        return "名字:%s 血量:%d 攻击力:%d" % (self.name,self.hp,self.atk)
# 悟空
wukong = Hero("悟空", 4000, 400)
# 默认情况下 打印的是对象的16进制地址
# 如果类中实现了__str__方法 如果打印对象名 会输出的是__str__方法中的返回值(字符串)
print(wukong)

====================================================
运行结果:
名字:悟空 血量:4000 攻击力:400

  本来print(wukong)返回的是对象wukong的十六进制内存地址,代表已经创建对象wukong成功,现在也代表创建对象成功,不过上面代码重写了__str__方法,返回的内容变成了我们想要的结果

 

  1.3、__del__方法

    监听对象销毁,如运行完成代码后运行,或使用del()函数删除对象时运行

    当删除对象时,python解释器也会默认调此方法;当使用del() 删除变量指向的对象时,则会减少对象的引用计数。如果对象的引用计数不为1,那么会让这个对象的引用计数减1,当对象的引用计数为0的时候,则对象才会被真正删除(内存被回收)

    调用__del__方法的情况:1、程序运行完成后自动会调用此方法;2、主动使用del()函数删除对象时也会自动调用此 方法

class Hero(object):

    # 构造方法
    def __init__(self, name):
        # 设置属性的值
        self.name = name

    # 输出一个字符串(追踪对象属性信息变化)
    def __str__(self):
        return "名字:%s" % self.name

    # 监听对象销毁后会走的方法
    def __del__(self):
        print("再见")
kk = Hero('影戏')
kk1 = kk
kk2 = kk
# 删除对象
del kk
del kk1
del kk2
# 保存程序不结束
input()

===============================================
运行结果出现:再见,但程序未运行结束,说明此时已经自动调用了__del__方法
# 当有变量保存了一个对象的引用时,此对象的引用计数就会加1;
# 当使用del() 删除变量指向的对象时,则会减少对象的引用计数。如果对象的引用计数不为1,那么会让这个对象的引用计数减1,当对象的引用计数为0的时候,则对象才会被真正删除(内存被回收)

 

  1.4、__mro__方法

    用于查看多继承的继承顺序,有多个父类时,要查看父类的继承顺序,

    运行代码:print(子类名.mro())或print(子类名.__mro__),如:print(Heigou.mro())或print(Heigou.__mro__)

 

  1.5、__new__方法

    监听python使用其创建对象,并返回对象给__init__*(此方法先与__init__运行)

    只有继承于object的新式类才能有__new__方法,__new__方法在创建类实例对象时由Python解释器自动调用,一般不用自己定义

    Python默认调用该类的直接父类的__new__方法来构造该类的实例,如果该类的父类也没有重写__new__,那么将一直按此规矩追溯至object的__new__方法,因为object是所有新式类的基类

class Person(object):

    # 监听python使用其创建对象,并返回对象给__init__
    # 为什么没写__new__也可正常创建对象(因为这是object的子类,继承了object的__new__)
    def __new__(cls, *args, **kwargs):
        print('__new__')
        return object.__new__(cls)#这是固定格式,委托父类帮忙创建一个对象
    # 构造方法(监听python使用其类创建对象完成,给这个对象设置属性)
    def __init__(self):
        print('__init__')
        self.name = '小明'
    # 监听对象属性形象变化,此方法必须返回的是字符串,否则报错
    def __str__(self):
        return '名字:%s ' % self.name
    # 监听对象销毁的
    def __del__(self):
        print('再见')
xiaoming = Person()
print(xiaoming)

   1.6、__name__方法

    在同一个.py文件中,打印__name__结果均为__main__;把一个test.py文件的打印__name__的代码封装成函数,导入另外一个模块cesh.py使用,打印出来的结果是test.py的模块名字test

    一般与__main__一起作为自测函数的条件使用,用if __name__ == '__main__'作为条件,使自测函数自在本模块运行生效

    如test.py

name = '制作模块'
def add2num(a,b):
    return a + b
class Person(object):
    def eat(self):
        print('人会吃饭')
def dayin__name():
    print(__name__)

# 用来测试代码的函数(自测函数),一般命名main()
def main():
    print(name)

    ret = add2num(12,32)
    print(ret)

    p = Person()
    p.eat()

# 调用测试函数
if __name__ == '__main__':
    main()

dayin__name()
=========================================
dayin__name()运行的结果是:__main__

  创建一个测试模块ceshi.py调用test.py

import test
# 需要测试test模块,定义 一个本模块的测试函数
def main():
    print(test.name)
      ret = test.add2num(222,22)
    print(ret)

    p = test.Person()
    p.eat()

# 调用测试函数
if __name__ == '__main__':
    main()

test.dayin__name()

==========================================
test.dayin__name()运行结果:test

 

 

 

 

创建对象调用的魔法方法顺序:

Python里创建对象的大致流程:当用一个类创建一个对象时,Python先执行类或父类或object基类的__new__方法创建对象,创建成功后开始运行__init__方法,初始化对象,给对象添加属性............直到程序运行完成(或执行函数del()删除对象),执行__del__方法,回收内存

 

推荐阅读