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__方法,回收内存