多态

1.什么是多态?
多态指的是同一种类型的事物,不同的形态。

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

  多态的表现 “形式之一” 就是继承:
    - 先抽象,再继承

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

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

# 动物类
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()

抽象类

1.什么是抽象类?
  在python内置的abc模块中,有一个抽象类。

2.抽象类的作用:
  让子类必须遵循父类的编写规范。

3.如何实现抽象类
  - 父类需要继承abc模块中,metaclass=abc.ABCMeta
  - 在父类的方法中,需要装饰上 abc.abstractmethod

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

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

import abc

# 父类
class Animal(metaclass=abc.ABCMeta):
# 方法 吃
@abc.abstractmethod
def eat(self):
pass
# 方法 叫
@abc.abstractmethod
def speak(self):
pass # 猪类
class Pig(Animal):
def run(self):
pass
def eat(self):
print('bia唧...')
def speak(self):
print('哼哼哼...') print(Pig.__dict__)
print(Animal.__dict__)
pig_obj = Pig()

鸭子类型

1.什么是鸭子类型?
  不同的对象,只要长得像鸭子,动作行为像鸭子,那它就是鸭子!

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

2.为什么要有鸭子类型?
  不同对象,先抽象出相同类型的方法,给他们定制一套统一的规范。
  所有的类,在定义时都按照统一的规范进行编写。

  - 多态的三种表现形式:
    - 继承父类 ****
      - 耦合度高,程序的可扩展性低

    - 继承抽象类 ***
      - 耦合度极高,程序的可扩展性极低

    - 鸭子类型: *****
      - 耦合度低,程序的可扩展性高

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

# 猪类
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("汪汪汪...")

多态之炫技

# 猪类
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("汪汪汪...") dog = Dog()
pig=Pig()
cat=Cat() # 多态之炫技
def SPEAK(animal):
animal.speak() SPEAK(dog)
SPEAK(cat)
SPEAK(pig) str1 = 'tank is very handsome!!!'
list1 = ['tank', 'is', 'very', 'handsome!!!'] # 自定义统计长度函数
def LEN(obj):
return obj.__len__() print(LEN(str1)) #
print(LEN(list1)) #

classmethod 与 staticmethod

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

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

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

- 对象的绑定方法:
  - 由对象来调用,由谁来调用,会将谁(对象)当做第一个参数传入。

- 类的绑定方法:
  - 由类来调用,由谁来调用,会将谁(类)当做第一个参数传入。

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

# classmethod_Demo:
class DB:
__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) # 查看数据方法
@classmethod
def check_db(cls, user, pwd, role): # cls --》指的是类
# 在类方法内部调用类产生一个实例 ---》 对象
obj = cls(user, pwd, role)
# 1.查看数据前,必须要通过校验
if obj.user == 'tank' and obj.pwd == '' and obj.role == 'admin':
print('检验通过..')
print(cls.__data)
return cls.__data DB.check_db('tank', '', 'admin')
obj=DB('tank','123','admin')
obj.check_db('tank','123','admin') # 也可以,第一个传入参数依然是类,但没什么意义
# staticmethod_Demo:
class Foo:
@staticmethod
def func(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:
class Foo:
pass class Boo:
pass foo_obj = Foo()
boo_obj = Boo() print(isinstance(foo_obj, Foo)) # True
print(isinstance(boo_obj, Foo)) # False # issubclass
class Father:
pass class Sub(Father):
pass class Foo:
pass print(issubclass(Sub, Father)) # True
print(issubclass(Foo, Father)) # False

反射

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

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

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

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

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

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

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

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

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

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

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) # # 若属性不存在,则返回默认值
res = getattr(foo_obj, 'z', '默认值')
print(res) # 默认值 # setattr
setattr(foo_obj,'x',40)
print(getattr(foo_obj,'x')) #
# 为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
# 反射应用:
class FileControl: def run(self):
while True:
# 让用户输入上传或下载功能的命令:
user_input = input('请输入 上传(upload) 或 下载(download) 功能:').strip() # 通过用户输入的字符串判断方法是否存在,然后调用相应的方法
if hasattr(self, user_input):
func = getattr(self, user_input)
func()
else:
print('输入有误!') def upload(self):
print('文件正在上传...') def download(self):
print('文件正在下载...') file_control_obj = FileControl()
file_control_obj.run()

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

# 代码同上,用来测试反射里面类型变化
class choose:
def run(self):
while True:
cmd = input('请输入命令:').strip()
if hasattr(self,cmd):
print(getattr(self,cmd)) # 把字符串转化为方法
# <bound method choose.load of <__main__.choose object at 0x00000000022A5F28>>
print(type(getattr(self,cmd)))
# <class 'method'>
getattr(self,cmd)() # 运行方法
else:
print('输入有误') def load(self):
print('load')
def down(self):
print('down') obj = choose()
print(type(obj.load)) # <class 'method'>
obj.run()

python基础语法17 面向对象4 多态,抽象类,鸭子类型,绑定方法classmethod与staticmethod,isinstance与issubclass,反射的更多相关文章

  1. python基础语法14 面向对象

    面向对象 1.什么是面向对象? 面向对象是一门编程思想! - 面向过程编程思想: 核心是 “过程” 二字,过程指的是解决问题的步骤,即先干什么再干什么! 基于该编程思想编写程序,就好比在设计一条工厂流 ...

  2. python基础语法_3面向对象

    http://www.runoob.com/python3/python3-class.html https://www.imooc.com/learn/317 慕课网:987809563@qq.co ...

  3. python基础语法19 面向对象总结,pickle保存对象注意事项

    面向对象的三大特性: 继承,封装,多态 多态的三种表现形式:鸭子类型,继承父类,继承抽象类 pickle保存对象注意事项 class Foo: y = 20 def __new__(cls, *arg ...

  4. day25 面向对象之多态和鸭子类型

    1.封装方法 如何封装:给方法名称前面加上双下划线 # ATM 的取款功能 # 1.插入银行卡 2.输入密码 3.选择取款金额 4.取款 class ATM: def __insert_card(se ...

  5. python 封装,隐藏属性,绑定方法classmethod和staticmethod

    [封装] 隐藏对象的属性和实现细节,仅对外提供公共访问方式. [好处] 1. 将变化隔离: 2. 便于使用: 3. 提高复用性: 4. 提高安全性: [封装原则] 1. 将不需要对外提供的内容都隐藏起 ...

  6. python基础语法15 面向对象2 继承,多态,继承json模块中JSONEncoder,并派生出新的功能

    继承 1.什么是继承? 继承是一种新建类的方式,新建的类称之为子类或派生类,继承的父类称之为基类或超类. - 在Python中,一个子类可以继承多个父类.(面试可能会问) - 在其它语言中,一个子类只 ...

  7. python基础语法20 面向对象5 exec内置函数的补充,元类,属性查找顺序

    exec内置函数的补充 exec: 是一个python内置函数,可以将字符串的代码添加到名称空间中; - 全局名称空间 - 局部名称空间 exec(字符串形式的代码, 全局名称空间, 局部名称空间) ...

  8. python基础语法16 面向对象3 组合,封装,访问限制机制,内置装饰器property

    组合: 夺命三问: 1.什么是组合? 组合指的是一个对象中,包含另一个或多个对象. 2.为什么要用组合? 减少代码的冗余. 3.如何使用组合? 耦合度: 耦: 莲藕 ---> 藕断丝连 - 耦合 ...

  9. 【python基础语法】常用内置函数、关键字、方法和之间的区别(小结)

    ''' 关键字: False:bool数据类型 True:bool数据类型 None:表示数据的内容为空 and:逻辑运算符:与 or:逻辑运算符:或 not:逻辑运算符:非 in:身份运算符,判断变 ...

随机推荐

  1. Oracle--RMAN Recover 缺失的归档操作

    一,环境简介 Oracle RMAN 备份的恢复分2个步骤:RESTRE 和 RECOVER.在这里回复的时候是依赖者归档文件的,当周一完成数据全备,保留归档的情况下,后期数据有问题,恢复的时候发现少 ...

  2. 守护进程--Supervisor

    01,介绍 02,安装部署 yum install python-setuptoolseasy_install supervisor 03,使用说明 supervisor安装成功之后,没有提供默认的配 ...

  3. x58平台 服务器电源配置 tdp

    我的机器配置: 处理器:    Intel(R) Xeon(R) CPU           X5660  @ 2.80GHz *2主板:    TYAN Tyan Tank GT20-B7002LN ...

  4. MongoDB出现The default storage engine 'wiredTiger' is not available之问题解决

    问题描述:低版本MongoDB存在该问题(版本为3.x),高版本则无该问题. 参考解决问题链接:MongoDB学习—(1)安装时出现The default storage engine ‘wiredT ...

  5. 手把手教你 通过 NuGet.Server 包 搭建nuget服务器,并使用桌面工具上传 nuget 包,免命令行

    新建web项目 工具:VS2013 版本:.Net Framework 4.6,低版本也行,不过要找到对应版本的Nuget.Server 装了NuGet客户端(百度如何安装) WebForm或MVC都 ...

  6. 自动化部署Ruby on Rails应用(docker + jenkins)

    docker安装参考链接docker官网jenkins中文官网 我的博客网站已经迁移到了https://johnnyting.github.io/,如果有兴趣的可以关注下.下面文章格式可能有点乱,可以 ...

  7. 如何打造难用,bug多的产品

    本文纯属吐槽,如有雷同,绝非巧合.长期更新,欢迎一起吐槽. 没有产品规划 需求方提出需求后,直接开发,无需经过产品规划,用开发的思维搞出来!于是我们得到了一堆功能的集合.这个集合可以让刚上手的新用户一 ...

  8. Django的学习——全局的static和templates的使用

    一.问题 首先我们在进行Django框架搭建的时候我们需要建立一个全局的变量,一是为了实现代码的复用,二是为了方便管理,如下图的样式 二.解决 1.修改setting里面的配置文件①templates ...

  9. git账户配置

    一.生成github的ssh key ssh-keygen ssh-keygen -t rsa -f ~/.ssh/zzf073_rsa -C zzf073@163.com 二.配置账户公钥 1.查看 ...

  10. drf--版本控制

    目录 作用 内置版本控制 局部使用 全局使用 案例 源码分析 作用 因为程序在不停的更新迭代,新版和旧版差别比较大,但此时有些用户没用进行更新,还是访问的旧版,此时就需要进行版本控制,让用户体验更好 ...