类的三大特性(继承, 封装, 多态)
类的三大特性之继承
class Animals:
a_type = "哺乳动物"
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def eat(self):
print("%s is eating ...."%self.name)
class Person(Animals):
a_type = "高级动物"
def talk(self):
print("person %s is talking..."%self.name)
def eat(self):
print("person %s is eat zaofan"%self.name)
class Pig(Animals):
def chase_rabbit(self):
print("pig %s chase rabbit..."%self.name)
p = Person("xdd",22,"Man")
p.talk()
p.eat()
print(p.a_type)
pig = Pig("jack",2,"pig")
pig.chase_rabbit()
print(pig.a_type)
重写父类方法 - 单继承
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。# -*- coding:utf-8 -*-
class Animals:
a_type = "哺乳动物"
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def eat(self):
print("%s is eating ...."%self.name)
class Person(Animals):
a_type = "高级动物"
def __init__(self,name,age,sex,hobbie):
#Animals.__init__(self,name,age,sex)
#super(Person,self).__init__(name,age,sex)
super().__init__(name,age,sex)
self.hobbie = hobbie
def talk(self):
print("person %s is talking..."%self.name)
def eat(self):
super().eat() #super继承执行父类的方法
print("person %s is eat zaofan"%self.name)
class Pig(Animals):
def chase_rabbit(self):
print("pig %s chase rabbit..."%self.name)
p = Person("xdd",22,"Man","read book")
p.talk()
p.eat()
print(p.a_type,p.hobbie)
类的多继承
按顺序从左到右继承
继承顺序分为两种:这是简单的理解,深度理解完全不是这样的
深度优先:先找M -MB - S -SB
广度优先: 一层一层的找 先M -S - MB -SB
实际上在python3上类的多继承的情况下,使用的是C3算法,既不能说是广度也不能说是深度
Python 中,类有两种写法: 在python 3上默认就是新式类
Class A: #经典类
Class B(object): #新式类
C3算法十分复杂,所以有兴趣去了解
如果想要简单快速的查看一个类的继承方式可以使用:
Print(类名.mro())
# -*- coding:utf-8 -*-
class ShenXianBase:
def fight(self):
print("元祖在打架")
class ShenXian(ShenXianBase):
def fly(self):
print("shenxian is fly")
def fight(self):
print("神仙在打架")
class MonkeyBase:
def fight(self):
print("猿猴在打击")
class Monkey(MonkeyBase):
def eat_peach(self):
print("monkey like eat taozi ")
def fight(self):
print("猴子在打击")
class Monkeyking(ShenXian,Monkey):
def play_goden_stick(self):
print("sun wu kong play jinjubang")
sxz = Monkeyking()
sxz.eat_peach()
sxz.fly()
sxz.play_goden_stick()
sxz.fight()
print(Monkeyking.mro())
类的三大特性之--封装 :私有变量都是加两个下划线__
self.__name 将变量变成私有的
方法也可以变成私有的
def __sayhi():
# -*- coding:utf-8 -*-
class Person(object):
def __init__(self,name,age):
self.__name = name
self.__age = age
def __get_name(self):
print("name is %s"%self.__name)
p = Person("xdd",22)
print(p._Person__name) #强行访问私有变量
p._Person__name = "jack" #强行修改私有变量
p._Person__get_name() #强行访问私有方法
类的三大特性之- 多态
有时一个对象会有多种表现形式,比如网站页面有button按钮,可以有正方形的圆的,方的,但是他们有一个共同的调用方法onClick()
# -*- coding:utf-8 -*-
#多态
class Dog(object):
def sound(self):
print("wang wang wang ...")
class Pig(object):
def sound(self):
print("heng heng heng ...")
def animals_sound(obj1):
obj1.sound()
d = Dog()
p = Pig()
animals_sound(d)
animals_sound(p)
# -*- coding:utf-8 -*-
#多态2
class Documents(object):
def __init__(self,name):
self.name = name
def show(self):
raise NotImplementedError("Subclass must implement abs")
class Pdf(Documents):
def show(self):
return "show pdf contents"
class Word(Documents):
def show(self):
return "show Word contents"
pdf = Pdf("xixixi.pdf")
word = Word("yyy.word")
obj = [pdf,word]
for o in obj:
print(o.show()) # 这个show方法就是接口上边的pdf,word就是形态
类方法,静态方法:
类方法:
类方法通过@classmethod装饰器来装饰一下即只能访问类的变量,不能访问实例变量
# -*- coding:utf-8 -*-
class Dog(object):
name = 'gouzi'
def __init__(self,name):
self.name = name
@classmethod
def eat(self):
print("dog %s is eating ...."%self.name)
d = Dog("xdd")
d.eat()
为什么不能访问实例变量,因为传进来的值不是实例本身,而是类本身,加上classmethod方法就会变成这样,去掉classmethod,传进来的就是实例本身了.
作用:
# -*- coding:utf-8 -*-
class Stu(object):
__stu_num = 0
def __init__(self,name):
self.name = name
self.add_stu(self)
@classmethod
def add_stu(cls,obj):
if obj.name:
cls.__stu_num += 1
print("生成一个新学生",cls.__stu_num)
s = Stu('j')
s2 = Stu('k')
s3 = Stu('o')
s4 = Stu('5')
静态方法:
@staticmethod 既不能访问实例变量,又不能访问类变量
静态方法割断了他和类或实例的任何关系
属性方法property
把一个方法变成一个静态的属性
class Stu(object):
def __init__(self,name):
self.name = name
@property
def fly(self):
print("jack is flying")
s = Stu('rain')
s.fly #不需要加括号了,调用这个方法
神奇的反射:
可以通过字符串的形式来操作对象的属性
Getattr 获取
Hsaattr 查询
Setattr 赋值
Delattr 删除
如何反射一个文件下指定的对应的属性
__name__ 在当前文件主动执行的情况下(不是被导入执行),__name__ 就等于 __main__
在被其他文件当模块执行的时候,就等于这个文件(模块)名
# -*- coding:utf-8 -*-
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def drink(self):
print("drink water ...")
def talk(self):
print("talking...")
p = Person('xdd',22)
#查询
if hasattr(p,"name"):
print("11111")
user_command = input('>>').strip()
if hasattr(p,user_command):
fun = getattr(p,user_command)
fun()
#获取
a = getattr(p,"age")
print(a)
#修改,增加
setattr(p,"sex","Man")
print(getattr(p,'sex'))
setattr(Person,"speak",talk)
p.speak()
#删除
delattr(p,"age")
if __name__ == "__main__": #只会被在别的模块导入的时候发挥作用
print('jaja')
#动态获取当前模块下的属性
import sys
mod = sys.modules["__main__"]
if hasattr(mod,"p"):
o = getattr(mod,"p")
print(o.drink)
动态加载模块
# -*- coding:utf-8 -*-
#动态加载模块 ,热加载,在程序运行中,加入一个模块
#__import__("Property") #解释器用的
import importlib
importlib.import_module("Property") #python官方推荐使用的 和上边的效果是一样的
importlib.import_module("function_def.List_builder")
反射的再应用:
#-*- coding:utf-8 -*-
class User(object):
def __init__(self):
print("welcome to yingxionglianmeng")
def login(self):
print("login...")
def register(self):
print("zhucejianmian...")
def disk(self):
print("welcome to save disk")
u = User()
while True:
user_cmd = input(">>").strip()
if hasattr(u,user_cmd):
getattr(u,user_cmd)()

