一、魔术方法
- 以'__'包起来的方法
- 魔术方法不需要调用就可以自动执行
- 常用的四种魔术方法:__init__();__new__();__del__();__str__()
(1)__init__():
- 初始化方法,类实例化时初始化对象
- 无返回值
class Person: nose=1 leg=2 def __init__(self): self.nose=1 self.leg=2 p1=Person() print(p1.__dict__)
输出:{'nose': 1, 'leg': 2}
- 传参(init括号里面为形参,self后面是对象的属性)
class Person: nose=1 leg=2 def __init__(self,name): self.name=name self.nose=1 self.leg=2 p1=Person("六六六") print(p1.__dict__)
输出:{'name': '六六六', 'nose': 1, 'leg': 2}
(2)__new__():
- 实例化对象方法
- 在实例化的时候触发
class Person: def __new__(cls): print("new方法被触发") # 实例化对象 p1=Person()
输出:new方法被触发
- 无返回值值时,实例化结果为None
- 管理控制对象的生成
class Person: def __new__(cls): print("new方法被触发") return 1 # 实例化对象 p1=Person() print(p1)
输出:
new方法被触发 1
- 一个 cls 接收当前类,其他的参数根据实例化的参数决定
- 实例化对象是 Object 类底层实现,其他类继承了 Object 的__new__ 才能够实现实例化对象
class Person: def __new__(cls,num): print(cls) if num=='1': return object.__new__(cls) else: return None # 实例化对象 p1=Person('1') print(p1)
输出:
<class '__main__.Person'> <__main__.Person object at 0x00000287DF4CD5E0>
自己控制对象的生成,上面代码示例中,只有为1的时候才生成对象
(3)__del__():
- 析构魔术方法
- 当所有代码程序执行完成则会进行垃圾回收,也叫内存释放,这时就会触发__del__方法
class Person: def __del__(self): print("del方法被触发") p1=Person() print("*****")
输出:
*****
del方法被触发
- 使用 del 对象名显示删除引用关系时,如果此操作将某块地址空间的最后一个引用关系给删除,会触发__del__方法
class Person: def __del__(self): print("del方法被触发") p1=Person() del p1 print("*****")
输出:
del方法被触发
*****
- 使用完对象时回收资源,没有指针引用的时候会调用,绝大多数时候 不需要重写
- 无返回值
(4)__str__():
- 当print()时想看到更多信息时,可以重写__str__方法
- 重写:用子类的方法覆盖父类的方法
- 使用print()的时候触发
class Person: name='六六六' def __str__(self): print("str方法被触发") return self.name p1=Person() print(p1)
输出:
str方法被触发
六六六
注意:返回值必须是字符串类型
- 使用str()的时候触发
class Person: name='六六六' def __str__(self): print("str方法被触发") return self.name p1=Person() str(p1) print("*****")
输出:
str方法被触发
*****
- 作用:print()时可以自定义输出更多有用信息
二·、继承和多态
1、继承
- 继承允许我们定义继承另一个类的所有方法和属性
- 父类:继承的类
- 子类:从另一个类继承的类
- 单继承:一个子类只继承了一个父类。
class Person: def sing(self): print("唱歌...") class Boy(Person): pass b1=Boy() b1.sing()
输出:唱歌...
子类中虽然没有sing函数,但是它继承了父类,可以直接调用
要给上面程序中添加一个其他方法时,该如何写呢,是在子类中添加还是父类中添加呢?实际上是都可以的
有多个子类的时候,要想让子类特有某个方法,这时需要添加到子类中去
代码示例:
class Person: def sing(self): print("%s唱歌..."%self.name) def __init__(self, name,age): self.name=name self.age = age class Boy(Person): pass class Girl(Person): def dance(self): print("%s跳舞..."%self.name) b1=Boy("六六六",6) b1.sing() g1=Girl("七七七",7) g1.dance()
输出:
六六六唱歌...
七七七跳舞...
- 多继承:一个子类继承多个父类
格式:单继承在类()中写1个父类的名字,多继承在()中写多个父类名字,用","隔开
多继承使定义子类的功能更加灵活
class Person: def sing(self): print("唱歌...") class Child: def dance(self): print("跳舞...") class Boy(Person,Child): pass b1=Boy() b1.sing() b1.dance()
输出:
唱歌...
跳舞...
2、重写
- 有时发现子类继承的父类的方法不能完全满足子类对象的需求,则此时就需要在子类中定义一个与父类相同的名字的方法
- 重写是子类中定义了与父类名字相同的方法
- 会优先去子类中找,子类中没有找到才会去父类
class Person: def sing(self): print("唱歌...") def dance(self): print("跳舞...") class Child(Person): def sing(self): print("唱唱唱...") p1=Person() p1.sing()
c1=Child() c1.sing()
输出:
唱歌...
唱唱唱...
3、super方法
- 在子类重写的方法中通过调用父类中被重写的方法
- super().父类方法名()
- 可以调用父类中的方法名
class Person: def sing(self): print("%s唱歌..."%self.name) def dance(self): print("%s跳舞..."%self.name) def __init__(self, name): self.name = name class Child(Person): def sing(self): super().sing() print("%s唱唱唱..."%self.name) p1=Person("六六六") p1.sing() c1=Child("七七七") c1.sing()
输出:
六六六唱歌...
七七七唱歌...
七七七唱唱唱...
4、多态
- 字面理解就是多种形态
- 实现多态前提:继承和重写
- 作用:增加程序灵活性、增加程序可扩展性
class Person(): def demo(self): print("六六六") class Child(Person): def demo(self): print("七七七") class Boy(Person): def demo(self): print("八八八") def func(obj): obj.demo() if __name__ == "__main__": c1=Child() b1 = Boy() func(c1) func(b1)
输出:
七七七
八八八
疑问:
多继承的时候可以这样写吗?
class Person: def sing(self): print("唱歌...") class Child(Person): def dance(self): print("跳舞...") class Boy(Person,Child): pass c1=Child() c1.sing() b1=Boy() b1.sing() b1.dance()
结果:程序报错
解决:修正后代码如下(将Person与Child交换一下位置)
class Person: def sing(self): print("唱歌...") class Child(Person): def dance(self): print("跳舞...") class Boy(Child,Person): pass c1=Child() c1.sing() b1=Boy() b1.sing() b1.dance()
输出:
唱歌... 唱歌... 跳舞...
原因:类Boy想要继承Person和Child,由于Child已经继承Person了,写成class Boy(Person,Child)错误形式时,python无法确定先查找哪些类的方法,于是无法覆盖定义在Person中定义的方法。
标签:__,12,进阶,self,Person,面向对象编程,print,class,def From: https://www.cnblogs.com/0925-LFH/p/16924746.html