今日学习总结:
一、多态:
01.什么是多态?
多态指的是同一种类型的事物,不同的形态。
-动物
猪
狗
猫
-笔
铅笔
钢笔
毛笔
02.多态的目的?
多态 也称之为 多态性,目的是为了 在不知道对象具体的类型的情况下,统一对象调用方法的规范。
多态的表现 形式之一 就是继承:
先抽象,再继承
父类:定制一套统一的规范。
子类:遵循父类的统一的规范。
注意:在python中,不会强制限制子类必须遵循父类的规范,所以出现了抽象类。
03.多态的实现?
例子:1.继承父类
# 动物类
class Animal:
def eat(self):
pass
def speak(self):
pass
# 猪类
class Pig(Animal):
def eat(self):
print('bia唧...')
def speak(self):
print('哼哼哼...')
# 猫类
class Cat(Animal):
def eat(self):
print('咬ji 咬ji....')
def speak(self):
print('喵喵喵...')
# 狗类
class Dog(Animal):
def eat(self):
print('舔 ji 舔ji...')
def speak(self):
print('汪汪汪...')
animal1 = Dog()
animal2 = Pig()
animal3 = Cat()
# 让动物们叫起来
animal1.speak()
animal2.speak()
animal3.speak()
二、抽象类
01.什么是抽象类?
在python内置的abc模块中,有一个抽象类
02.为什么使用抽象类?
让子类必须遵循父类的编写规范。
03.如何实现抽象类?
父类需要继承abc模块中的 metaclass=abc.ABCMeta
在父类的方法之上,需要装饰上 abc.abstractmethod
注意:在python中,不推荐使用抽象类
注意:子类必须按照父类的方法编写规范,缺一不可(只要父类中有几个抽象方法,子类)
例子:2.继承抽象类
import abc
# 父类
class Animal(metaclass=abc.ABCMeta):
# 方法 吃
@abc.abstractmethod
def eat(self):
pass
# 方法 叫
@abc.abstractmethod
def speak(self):
pass
# 猪类
#这样会出错,因为没有遵循父类,加上metaclass=abc.ABCMeta @abc.abstractmethod会强制子类要去遵循父类,否则会报错
# class Pig(Animal):
#
# def run(self):
# pass
#
# def chi(self):
# print('bia唧...')
#
# def tell(self):
# print('哼哼哼...')
# 猪类
class Pig(Animal):
def run(self):
pass
def eat(self):
print('bia唧...')
def speak(self):
print('哼哼哼...')
pig_obj = Pig()
pig_obj.eat()
三、鸭子类
01.什么是鸭子类型?
不同的对象,只要长得像鸭子,动作行为像鸭子,那他就是鸭子。
鸭子类型是多态的一种表现形式。
02.为什么要有鸭子类型?
不同的对象,先抽象出相同的类型的方法,给他们定制一套统一的规范。
所有的类,在定义时都按照统一的规范进行编写。
注意:在python中,强烈推荐使用鸭子类型。
03.如何实现鸭子类型?
例子:3.鸭子类型
# 猪类
class Pig:
def eat(self):
print('bia唧...')
def speak(self):
print('哼哼哼...')
# 猫类
class Cat:
def eat(self):
print('咬ji 咬ji....')
def speak(self):
print('喵喵喵...')
# 狗类
class Dog:
def eat(self):
print('舔 ji 舔ji...')
def speak(self):
print('汪汪汪...')
animal1 = Dog()
animal2 = Pig()
animal3 = Cat()
# 让动物们叫起来
animal1.speak()
animal2.speak()
animal3.speak()
总结:
多态的三种表现形式:
1.继承父类:耦合度高,程序的可扩展性低
2.继承抽象类:耦合度极高,程序的可扩展性极地
3.鸭子类型:耦合度低,程序的可扩展性高
四、classmethod与staticmethod
01、python中 默认是:对象的绑定方法。
02、classmethod :是一个装饰器,给在类内部定义方法中装饰,将类内部的方法变为‘类的绑定方法’
03、staticmethod:是一个装饰器,给在类内部定义方法中装饰,将类内部的方法变为‘非绑定方法’
例子:01
要求:输出__data的值
方法一:这是通过 对象去调用方法和属性 去实现要求
class DB:
__data='tank is very handsome!'
def __init__(self,user,pwd,role):
self.user=user
self.pwd=pwd
self.role=role
def chenck_db(self):
if self.user=='tank' and self.pwd==123 and self.role=='管理员':
print('通过验证。。。')
print(self.__data) #这是通过 对象去调用方法和属性 去实现要求
#return self.__data #这里写不写都行。
db_obj=DB('tank',123,'管理员')
db_obj.chenck_db()
要求输出__data的值
方法二: 这是通过 类去调用方法和属性 去实现要求
class DB:
__data='tank is very handsome!'
def __init__(self,user,pwd,role):
self.user=user
self.pwd=pwd
self.role=role
def chenck_db(self):
if self.user=='tank' and self.pwd==123 and self.role=='管理员':
print('通过验证。。。')
print(self.__class__.__data) #这是通过 类去调用方法和属性 去实现要求。因为self是db_obj,
#self.__class__ 是类自己
print(self.__class__) #<class '__main__.DB'>
#return self.__class__.__data #这里写不写都行
db_obj=DB('tank',123,'管理员')
db_obj.chenck_db()
例子:02
#04要求输出__data的值
class DB:
__data='tank is very handsome!'
def __init__(self,user,pwd,role):
self.user=user
self.pwd=pwd
self.role=role
@classmethod #这是用classmethod 装饰器,来绑定类的,可以用类名来调用函数。
def chenck_db(cls,user,pwd,role):
obj=cls(user,pwd,role) #这是在类内部产生一个实例
if obj.user=='tank' and obj.pwd==123 and obj.role=='管理员':
print('通过验证。。。')
print(cls.__data) #这是通过 类去调用方法和属性 去实现要求。因为cls是类自己
DB.chenck_db('tank',123,'管理员')
例子:03
class Foo:
@staticmethod #这是用staticmethod 装饰器,是非绑定的,可以用类名或者对象名来调用函数
def func(res):
print(res)
obj = Foo()
obj.func(123) # 对象调用非绑定方法
Foo.func(1234) # 类调用非绑定方法
五、isinstance与issubclass
是python的内置模块
01、isinstance: 判断一个对象是否是另一个类的实例。
- 如果是: True
- 如果不是: False
02、issubclass: 判断一个类是否是另一个类的子类。
- 如果是: True
- 如果不是: False
例子:01
#isinstance:
class Foo:
pass
class Boo:
pass
foo_obj = Foo()
boo_obj = Boo()
print(isinstance(foo_obj, Foo)) # True #判断foo_obj (对象)是不是 Foo(类) 的对象
print(isinstance(boo_obj, Foo)) # False #判断 boo_obj (对象) 是不是 Foo(类) 的对象
例子:02
# issubclass
class Father:
pass
class Sub(Father):
pass
class Foo:
pass
print(issubclass(Sub, Father)) # True 判断 Sub(类) 是不是在 Father(父类)中
print(issubclass(Foo, Father)) # False 判断 Foo(类) 是不是在 Father(父类)中
六、反射
01.什么是反射?
反射指的是通过 字符串对 对象的属性进行操作'''
02.反射的四个方法是python内置的:
- hasattr: 通过 “字符串” 判断对象的属性或方法是否存在。
- getattr: 通过 “字符串” 获取对象的属性或方法。
- setattr: 通过 “字符串” 设置对象的属性或方法。
- delattr: 通过 “字符串” 删除对象的属性或方法。
ps:普通的 查、取、改、删 属性或方法
class Foo:
def __init__(self, x, y):
self.x = x
self.y = y
obj=Foo()
obj.x = 10
print(obj.x) #查看属性的值
obj.x = 20 #修改属性的值
del obj.x #删除属性
用反射 进行 查改删 属性或方法
class Foo:
def __init__(self, x, y):
self.x = x
self.y = y
foo_obj = Foo(10, 20)
#hasattr:通过字符串x 判断对象中是否有 x属性。查属性
print(hasattr(foo_obj, 'x')) # True
print(hasattr(foo_obj, 'y')) # True
print(hasattr(foo_obj, 'z')) # False
#getattr:取属性的值,若属性不存在,则返回默认值
res = getattr(foo_obj, 'x')
print(res) # 10
res = getattr(foo_obj, 'z', '默认值')
print(res) # 默认值
#setattr:设置一个属性z,值为30 。增加一个属性
setattr(foo_obj, 'z', 30)
print(hasattr(foo_obj, 'z')) # True
#delattr:删除一个属性
delattr(foo_obj, 'x')
print(hasattr(foo_obj, 'x')) # False
ps:反射的应用:
class FileControl:
def run(self):
while True:
# 让用户输入上传或下载功能的命令:
user_input = input('请输入 上传(upload) 或 下载(download) 功能:').strip()
if hasattr(self, user_input): # 通过用户输入的字符串判断方法是否存在
func = getattr(self, user_input) #用getattr 来获取属性。在这里获取的是selfz这个对象
func() #相当于对象加上() 表示调用.相当于 调用类。既是file_control_obj()既是 FileControl()()
else:
print('输入有误!')
def upload(self):
print('文件正在上传...')
def download(self):
print('文件正在下载...')
file_control_obj = FileControl()
file_control_obj.run()