Python基础20 面向对象(3)多态、封装、反射

文章目录

  • 一、多态
    • 1、什么是多态
    • 2、多态小实验
  • 二、封装
    • 1、什么是封装
    • 2、内部属性的约定
  • 三、反射
    • 1、什么是反射
    • 2、四个实现自省的函数
      • (1)hasattr(object,name)
      • (2)getattr(object,name,default=None)
      • (3)setattr(object,name,value)
      • (4)delattr(object,name)
    • 3、反射的用途
    • 4、动态导入模块
  • 四、attr内置方法
    • 1、__getattr__()
    • 2、__delattr__()
    • 3、__setattr__()
  • 五、小实验1:包装标准类型
  • 六、小实验2:组合方式完成授权,改写文件处理函数

一、多态

1、什么是多态

多态是指对象通过他们共同的属性和方法来操作及访问,而不需要考虑他们具体的类。

s = "abc"
print(s.__len__())  # 3,等同len(s)l = [1, 3]
print(l.__len__())  # 2,等同len(l)

多态体现在由同一个类实例化出多个对象,这些对象执行相同的方法时,执行的过程和结果是不一样的。

class H2O:def __init__(self, name, tem):self.name = nameself.tem = temdef turn(self):if self.tem > 100:print("%s 变成了水蒸气" % self.name)elif self.tem < 0:print("%s 变成了冰" % self.name)else:print("%s 变成了水" % self.name)class Steam(H2O):pass
class Water(H2O):pass
class Ice(H2O):passs = Steam("s", 1000)
w = Water("w", 50)
i = Ice("i", -10)s.turn()    # s 变成了水蒸气
w.turn()    # w 变成了水
i.turn()    # i 变成了冰

2、多态小实验

模拟 len() 函数,对上述turn方法,做成函数形式。

# 接上述实例化代码后,补充如下代码
def turn(obj):obj.turn()turn(s) # s 变成了水蒸气
turn(w) # w 变成了水
turn(i) # i 变成了冰

二、封装

1、什么是封装

(1)装,即把一些属性装到一个容器中。封,即为隐藏。
(2)类就是一种容器,这本身就是一种封装。
(3)类中定义私有的属性,只有类的内部可以使用,外部无法访问。
(4)封装明确区分内外,内部的实现逻辑,外部无法知晓,并且为封装到内部的逻辑提供一个访问接口给外部使用。

2、内部属性的约定

python并没有严格限制外部访问内部属性,但把单下划线和双下划线开头的属性约定为内部属性。

class People:_age = 18__sex = "f"def __init__(self):passdef info(self):print("age %s,sex %s" %(self._age, self.__sex))
p1 = People()
print(People._age)  # 18 但下划线开头属性,外部可以直接访问
print(People._People__sex)  # f 双下划线开头属性,会在属性字典中重命名为_类__属性
p1.info()   # age 18,sex f 内部可以调用它们

三、反射

1、什么是反射

反射主要是指程序可以访问、检测、和修改它本身状态或行为的一种能力(自省)。

2、四个实现自省的函数

以下四个函数适用于类和对象。

(1)hasattr(object,name)

 判断name是否在object中。

(2)getattr(object,name,default=None)

  相当于执行object.name

(3)setattr(object,name,value)

  设置object的属性

(4)delattr(object,name)

 删除object中的name属性

class People:age = 18sex = "f"def __init__(self):self.age = self.agedef info(self):print("age %s,sex %s" % (self.age, self.sex))p1 = People()print(hasattr(p1, "age"))  # True 相当于判断p1.age是否可以被调用
getattr(p1, "info")()  # age 18,sex f 相当于调用p1.info
# getattr(p1, "info1")()  # 没有info1,则报错
print(getattr(p1, "info1", 10)) # 10 没有不报错,返回默认值setattr(p1,"func",lambda x:x*2)
print(p1.func(3))   # 6
print(p1.__dict__)  # {'age': 18, 'func': <function <lambda> at 0x000001623A680160>}
delattr(p1,"age")   # 删除age属性
print(p1.__dict__)  # {'func': <function <lambda> at 0x000001623A680160>}

3、反射的用途

可以事先定义接口,接口只有在被完成后才会真正执行,这实现了即插即用。
prog1代码:

class Ftp:def __init__(self):passdef put(self):print("执行put方法")

调用程序代码:

from prog1 import Ftp
f1 = Ftp()if hasattr(f1,"put"):func_get = getattr(f1,"put")func_get()
else:print("执行其他逻辑")

4、动态导入模块

动态导入模块就是基于反射实现的。
t.py代码:

def test1():print("I am test1")def _test2():print("I am test2")

执行模块代码:

module_t = __import__("d1.t")   # d1与执行模块在同级目录,t为d1的子文件
print(module_t) # <module 'd1' (namespace)>
module_t.t.test1()  # I am test1
from d1.t import *
_test2()  #报错
from d1.t import test1,_test2
_test2()    #不报错
from d1 import t
t._test2() # 不报错
import importlib
m = importlib.import_module("d1.t")
m._test2() # 不报错

四、attr内置方法

在不自定义这些内置方法时,程序会执行其自身的对应方法。

1、getattr()

在属性不存在时,会自动触发自定义的__getattr__()。属性存在时,不执行它,而是执行其自身的方法。

class Foo:def __init__(self,y):self.y = ydef __getattr__(self, item):print("执行我")f1 = Foo(10)
print(f1.y) # 10
print(getattr(f1,"y")) # 10
f1.aa # 执行我

2、delattr()

执行 del 对象.属性 时,会触发 __delattr__()

class Foo:x = 1def __init__(self,y):self.y = ydef __delattr__(self, item):print("执行我")self.__dict__.pop(item)f1 = Foo(10)
print(f1.__dict__)  # {'y': 10}
del f1.y    # 执行我
print(f1.__dict__)  # {}

3、setattr()

在执行对象.属性=value时,触发 __setattr__()

class Foo:x = 1def __init__(self,y):passdef __setattr__(self, key, value):print("执行我")self.__dict__[key] = valuef1 = Foo(10)
print(f1.__dict__)  # {}
f1.y = 11   # 执行我
print(f1.__dict__)  # {'y': 11}

五、小实验1:包装标准类型

重写列表类型:只能向列表中添加字符串元素;删除元素后,要返回该元素值。

class List(list):def append(self, obj):if type(obj) is str:super().append(obj)else:print("必须是字符串")l = List("ab")
print(l)    # ['a', 'b']
l.append(1) # 必须是字符串
print(l)    # ['a', 'b']
l.append("c")
print(l)    # ['a', 'b', 'c']

六、小实验2:组合方式完成授权,改写文件处理函数

授权是包装的一个特性。包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能,其他的则保持原样。授权的过程是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象为默认属性。

实验内容:写入文件内容加时间。其他文件处理函数的功能不变。

import time
class FileHandle:def __init__(self,filename,mode="r",encoding="utf-8"):self.f = open(filename,mode,encoding=encoding)def write(self,content):t = time.strftime("%F %X")self.f.write("%s %s" %(t,content))def __getattr__(self, item):return getattr(self.f,item)f1 = FileHandle("a.txt","w+")
f1.write("内存空间不足!\n")
f1.write("磁盘空间不足!")
f1.seek(0)
print(f1.read())
f1.close()'''a.txt内容
2024-02-22 15:57:05 内存空间不足!
2024-02-22 15:57:05 磁盘空间不足!
'''

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/696613.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

神秘人暗访:行政窗口为什么要开展神秘顾客调研

在竞争日益激烈的服务市场中&#xff0c;行政窗口作为公共服务的直接提供者&#xff0c;其服务质量的好坏直接关系到政府的形象和公众对政府的信任度。为了更好地满足市民的需求&#xff0c;提升服务质量&#xff0c;开展神秘顾客调查显得尤为重要。神秘顾客调查的必要性包括以…

内网穿透的应用-如何本地部署Elasticsearch搜索分析引擎实现并发布公网远程访问

文章目录 系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装 Cpolar4. 创建Elasticsearch公网访问地址5. 远程访问Elasticsearch6. 设置固定二级子域名 Elasticsearch是一个基于Lucene库的分布式搜索和分析引擎&#xff0c;它提供了一个分布式、多…

探索Flask框架:打造优雅而强大的Web应用

在当今互联网时代&#xff0c;Web应用的需求日益增长&#xff0c;而作为开发者&#xff0c;我们需要一个简洁明快、灵活可扩展的框架来满足这些需求。Flask框架作为一个Python微型框架&#xff0c;在其简洁的设计理念和丰富的扩展生态系统之间找到了完美的平衡&#xff0c;为我…

洛谷--二分(Java实现)

洛谷 B3627 立方根 题目描述 给定正整数 n&#xff0c;求 √n​。答案向下取整。 输入格式 仅一行&#xff0c;一个正整数 n。 输出格式 仅一行&#xff0c;一个正整数&#xff0c;表示√n。向下取整输出。 输入输出样例 输入 #1 27 输出 #1 3 输入 #2 100000 输…

ORACLE之 decode函数

语法&#xff1a; DECODE(expression, search1, result1, search2, result2, ..., default_result) 其中&#xff0c;expression是要进行比较的表达式&#xff0c;search1, search2等是可能的值&#xff0c;result1, result2等是对应的结果。如果expression等于search1&#x…

Java类的成员、继承、多态

当谈论Java类的成员、继承和多态时&#xff0c;我们谈论的是面向对象编程的基本概念。让我逐一介绍&#xff1a; 1. **成员**&#xff1a; - **字段&#xff08;Field&#xff09;**&#xff1a;也称为属性或变量&#xff0c;用于存储对象的状态信息。 - **方法&#xf…

防御保护第六次作业

需求: 8&#xff0c;分公司内部的客户端可以通过域名访问到内部的服务器 9&#xff0c;假设内网用户需要通过外网的web服务器和pop3邮件服务器下载文件和邮件&#xff0c;内网的FTP服务器也需要接受外网用户上传的文件。针对该场景进行防病毒的防护。 10&#xff0c;我们需要针…

C++模板从入门到入土

1. 泛型编程 如果我们需要实现一个不同类型的交换函数&#xff0c;如果是学的C语言&#xff0c;你要交换哪些类型&#xff0c;不同的类型就需要重新写一个来实现&#xff0c;所以这是很麻烦的&#xff0c;虽然可以cv一下&#xff0c;有了模板就可以减轻负担。 下面写一个适…

日常leetcode代码思路总结(持续更新)

日常leetcode代码思路总结&#xff08;持续更新&#xff09; 难易leecode题号题目描述思路简单121. 买卖股票的最佳时机只准一次买卖0表示持有&#xff0c;1表示不持有&#xff1b;dp[0][i] max(dp[0][i-1], -prices[i])&#xff1b;dp[1][i] max(dp[1][i-1], dp[0][i] pric…

Openwrt删除内核patch

环境说明 ubuntu-18.04 openwrt-21.02 安装quilt sudo apt install quilt quilt指令说明 Usage: quilt [--trace[=verbose]] [--quiltrc=XX] command [-h] ...quilt --version Commands are:add fold mail refresh snapshotannotate fork new rem…

基于springboot+vue的中小企业设备管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

H 桥逆变方式介绍(双极性)

单极性控制和双极性控制是说IGBT四个管子的控制 前面所说的单极性控制是其中一个管子开通、关闭另外一个管子持续开通 而双极性是四个管子中的两个管子同时导通&#xff0c;同时关断。彼此交替变化 所以当方波出现低电平时&#xff0c;是一对管子同时导通&#xff0c;出现高电…

2.21 Qt day2 菜单栏/工具栏/状态栏/浮动窗口、UI界面、信号与槽

思维导图 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;…

成像光谱遥感技术中的AI革命:ChatGPT应用指南

“成像光谱遥感技术中的人工智能革命&#xff1a;ChatGPT应用指南”&#xff0c;这是一门旨在改变您使用人工智能处理遥感数据的方式。将最新的人工智能技术与实际的遥感应用相结合&#xff0c;提供不仅是理论上的&#xff0c;而且是适用和可靠的工具和方法。无论你是经验丰富的…

golang实现延迟队列(delay queue)

golang实现延迟队列 1 延迟队列&#xff1a;邮件提醒、订单自动取消 延迟队列&#xff1a;处理需要在未来某个特定时间执行的任务。这些任务被添加到队列中&#xff0c;并且指定了一个执行时间&#xff0c;只有达到指定的时间点时才能从队列中取出并执行。 应用场景&#xff1…

智慧驿站_智慧文旅驿站_轻松的驿站智慧公厕_5G智慧公厕驿站_5G模块化智慧公厕

多功能城市智慧驿站是在智慧城市建设背景下&#xff0c;所涌现的一种创新型社会配套设施。其中&#xff0c;智慧公厕作为城市智慧驿站的重要功能基础&#xff0c;具备社会配套不可缺少的特点&#xff0c;所以在应用场景上&#xff0c;拥有广泛的需求和要求。那么&#xff0c;城…

高企认定的官方费用

高新技术企业认定并没有直接的“官费”&#xff0c;但是在申请高新技术企业认定过程中&#xff0c;企业可能会涉及到一些与政府部门相关的费用&#xff0c;主要包括以下几种情况&#xff1a; 1.知识产权相关费用&#xff1a;•申请专利、软件著作权等知识产权时需要向国家知识…

#12解决request中getReader()和getInputStream()只能调用一次的问题

目录 1、背景 2、解决方案 2.1、自定义HttpServletRequestWrapper 2.2、JsonRequestHeaderParamsHelper 2.3、HttpServletRequestReplacedFilter 2.4、使用 1、背景 当前系统Content-Type为application/json&#xff0c;参数接收方式采用RequestBody和RequestParam&#…

平时积累的FPGA知识点(10)

平时在FPGA群聊等积累的FPGA知识点&#xff0c;第10期&#xff1a; 41 ZYNQ系列芯片的PL中使用PS端送过来的时钟&#xff0c;这些时钟名字是自动生成的吗&#xff1f; 解释&#xff1a;是的。PS端设置的是ps_clk&#xff0c;用report_clocks查出来的时钟名变成了clk_fpga_0&a…

vue系列--通过js生成前端水印的方法

此方法开箱即用&#xff0c;在vue项目中import即可。 例如&#xff1a; //在vue组件中 import Watermark from /utils/watermark.js//在methods中 Watermark.set({color:"",text:""})//设置水印Watermark.remove() //删除水印 const watermark {}const…