python 抽象类的意义_python基础语法17 面向对象4 多态,抽象类,鸭子类型,绑定方法classmethod与staticmethod,isinstance与issubclass,反射**...

多态

1.什么是多态?

多态指的是同一种类型的事物,不同的形态。

2.多态的目的:

“多态” 也称之为 “多态性”,目的是为了 在不知道对象具体类型的情况下,统一对象调用方法的规范(比如:名字)。

多态的表现 “形式之一” 就是继承:

- 先抽象,再继承

父类: 定制一套统一的规范。(比如: 方法名统一)

子类: 遵循父类的统一的规范。(比如: 子类遵循父类方法名的统一)

注意: 在python中不会强制限制 子类 必须要遵循 父类 的规范,所以出现了抽象类。

#动物类

classAnimal:#方法 吃

defeat(self):pass

#方法 叫

defspeak(self):pass

#猪类

classPig(Animal):defeat(self):print('bia唧...')defspeak(self):print('哼哼哼...')#猫类

classCat(Animal):defeat(self):print('咬ji 咬ji....')defspeak(self):print('喵喵喵...')#狗类

classDog(Animal):defeat(self):print('舔 ji 舔ji...')defspeak(self):print('汪汪汪...')

animal1=Dog()

animal2=Pig()

animal3=Cat()#让动物们叫起来

animal1.speak()

animal2.speak()

animal3.speak()

抽象类

1.什么是抽象类?

在python内置的abc模块中,有一个抽象类。

2.抽象类的作用:

让子类必须遵循父类的编写规范。

3.如何实现抽象类

- 父类需要继承abc模块中,metaclass=abc.ABCMeta

- 在父类的方法中,需要装饰上 abc.abstractmethod

注意: 在python中不推荐使用抽象类。

注意: 子类必须按照父类的方法编写规范,缺一不可。(只要父类中有几个抽象方法,子类就必须要定义几个)

importabc#父类

class Animal(metaclass=abc.ABCMeta):#方法 吃

@abc.abstractmethoddefeat(self):pass

#方法 叫

@abc.abstractmethoddefspeak(self):pass

#猪类

classPig(Animal):defrun(self):pass

defeat(self):print('bia唧...')defspeak(self):print('哼哼哼...')print(Pig.__dict__)print(Animal.__dict__)

pig_obj= Pig()

鸭子类型

1.什么是鸭子类型?

不同的对象,只要长得像鸭子,动作行为像鸭子,那它就是鸭子!

鸭子类型是多态的一种表现形式。

2.为什么要有鸭子类型?

不同对象,先抽象出相同类型的方法,给他们定制一套统一的规范。

所有的类,在定义时都按照统一的规范进行编写。

- 多态的三种表现形式:

- 继承父类 ****

- 耦合度高,程序的可扩展性低

- 继承抽象类 ***

- 耦合度极高,程序的可扩展性极低

- 鸭子类型: *****

- 耦合度低,程序的可扩展性高

注意: 在python中,强烈推荐使用鸭子类型。

#猪类

classPig:defeat(self):print('bia唧...')defspeak(self):print('哼哼哼...')#猫类

classCat:defeat(self):print('咬ji 咬ji...')defspeak(self):print('喵喵喵...')#狗类

classDog:defeat(self):print('舔 ji 舔ji...')defspeak(self):print("汪汪汪...")

多态之炫技

#猪类

classPig:defeat(self):print('bia唧...')defspeak(self):print('哼哼哼...')#猫类

classCat:defeat(self):print('咬ji 咬ji...')defspeak(self):print('喵喵喵...')#狗类

classDog:defeat(self):print('舔 ji 舔ji...')defspeak(self):print("汪汪汪...")

dog=Dog()

pig=Pig()

cat=Cat()#多态之炫技

defSPEAK(animal):

animal.speak()

SPEAK(dog)

SPEAK(cat)

SPEAK(pig)

str1= 'tank is very handsome!!!'list1= ['tank', 'is', 'very', 'handsome!!!']#自定义统计长度函数

defLEN(obj):return obj.__len__()print(LEN(str1)) #24

print(LEN(list1)) #4

classmethod 与 staticmethod

classmethod与staticmethod都是python解释器内置的装饰器。 *******

classmethod:

是一个装饰器,给在类内部定义方法中装饰,将类内部的方法变为 “类的绑定方法”。

staticmethod:

翻译: 静态方法

是一个装饰器,给在类内部定义方法中装饰,将类内部的方法变为 “非绑定方法”。

- 对象的绑定方法:

- 由对象来调用,由谁来调用,会将谁(对象)当做第一个参数传入。

- 类的绑定方法:

- 由类来调用,由谁来调用,会将谁(类)当做第一个参数传入。

- 非绑定方法:

- 可以由对象或类来调用,谁来调用都是一个普通方法(普通函数),方法需要传入几个参数,就得传入几个。

#classmethod_Demo:

classDB:__data = 'tank is very handsome!!!'

def __init__(self, user, pwd, role):

self.user=user

self.pwd=pwd

self.role=role#@classmethod

#def init(cls, user, pwd, role): # cls --》指的是类

## 在类方法内部调用类产生一个实例 ---》 对象

#return cls(user, pwd, role)

#查看数据方法

@classmethoddef check_db(cls, user, pwd, role): #cls --》指的是类

#在类方法内部调用类产生一个实例 ---》 对象

obj =cls(user, pwd, role)#1.查看数据前,必须要通过校验

if obj.user == 'tank' and obj.pwd == '123' and obj.role == 'admin':print('检验通过..')print(cls.__data)return cls.__dataDB.check_db('tank', '123', 'admin')

obj=DB('tank','123','admin')

obj.check_db('tank','123','admin') # 也可以,第一个传入参数依然是类,但没什么意义

#staticmethod_Demo:

classFoo:

@staticmethoddeffunc(res):print(res)

obj=Foo()#对象调用非绑定方法

obj.func(123)#类调用非绑定方法

Foo.func(1234)

uuid 用于产生随机字符串的模块

import uuid #用于产生随机字符串的模块

#由时间戳以及某种算法组合而成,会产生一串世界上独一无二字符串。

print(uuid.uuid4()) #f93f9c3b-eef4-4001-922e-2124b48ca7ab

内置模块:isinstance与issubclass

isinstance与issubclass是python的内置模块: *******

- isinstance: 判断一个对象是否是另一个类的实例。

- 如果是: True

- 如果不是: False

- issubclass: 判断一个类是否是另一个类的子类。

- 如果是: True

- 如果不是: False

#isinstance:

classFoo:pass

classBoo:passfoo_obj=Foo()

boo_obj=Boo()print(isinstance(foo_obj, Foo)) #True

print(isinstance(boo_obj, Foo)) #False

#issubclass

classFather:pass

classSub(Father):pass

classFoo:pass

print(issubclass(Sub, Father)) #True

print(issubclass(Foo, Father)) #False

反射

反射: *******

反射指的是通过 “字符串” 对 对象的属性进行操作。

- hasattr: 通过 字符串 判断对象的属性或方法是否存在,存在返回True, 否则返回False。

hasattr(对象, '对象的属性或方法字符串')

- getattr: 通过 字符串 获取对象的属性或方法是否存在,存在返回获取属性或方法, 否则返回报错。

getattr(对象, '对象的属性或方法字符串', '默认值')

- setattr: 通过 字符串 设置(添加/修改)对象的属性或方法。

setattr(对象, '对象的属性或方法字符串', '属性的值')

- delattr: 通过 字符串 删除 对象的属性或方法,若属性不存在,则报错。

delattr(对象, '对象的属性或方法字符串')

# 注意: 反射的四个方法是python内置的。

classFoo: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

setattr(foo_obj,'x',40)print(getattr(foo_obj,'x')) #40#为foo_obj设置一个属性z,值为30

setattr(foo_obj, 'z', 30)print(hasattr(foo_obj, 'z')) #True

#delattr

delattr(foo_obj, 'x')print(hasattr(foo_obj, 'x')) #False

#反射应用:

classFileControl:defrun(self):whileTrue:#让用户输入上传或下载功能的命令:

user_input = input('请输入 上传(upload) 或 下载(download) 功能:').strip()#通过用户输入的字符串判断方法是否存在,然后调用相应的方法

ifhasattr(self, user_input):

func=getattr(self, user_input)

func()else:print('输入有误!')defupload(self):print('文件正在上传...')defdownload(self):print('文件正在下载...')

file_control_obj=FileControl()

file_control_obj.run()

以下为验证,反射中将输入输入字符创转化为方法

#代码同上,用来测试反射里面类型变化

classchoose:defrun(self):whileTrue:

cmd= input('请输入命令:').strip()ifhasattr(self,cmd):print(getattr(self,cmd)) #把字符串转化为方法

#>

print(type(getattr(self,cmd)))#

getattr(self,cmd)() #运行方法

else:print('输入有误')defload(self):print('load')defdown(self):print('down')

obj=choose()print(type(obj.load)) #

obj.run()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值