Python基础09_类和对象(下)迭代器和生成器函数式编程

一、类和对象(下)

1、封装

封装是指隐藏类的实现细节,让使用者不用关心这些细节;

封装的目的是让使用者通过尽可能少的方法(或属性)操作对象

Python的封装是假的(模拟的)封装

私有属性和方法

  • python类中以双下划线(__)开头,不以双下划线结尾的标识符为私有成员,私有成员只能使用方法来进行访问和修改

    • __开头的属性为类的私有属性,在子类和类外部无法直接使用

    • __开头的方法为私有方法,在子类和类外部无法直接调用

class A:def __init__(self):self.__a = 100  # 私有属性self.b = 200  # 实例属性# 私有方法def __m1(self):print("私有方法")a = A()
print(a.b)  # 200
print(a.a)  # AttributeError: 'A' object has no attribute 'a'
a.__m1()  # AttributeError: 'A' object has no attribute '__m1'
# 强行访问(不推荐)
print(a._A__a)  # 100
class B(A):def __init__(self):A.__init__(self)def m2(self):# 子类也无法访问self.__m1()print(f"{self.__a}")b_z = B()
b_z.m2()  # AttributeError: 'B' object has no attribute '_B__m1'

2、多态

定义

  • 字面意思"多种状态"

  • 多态是指在有继承/派生关系的类中,调用基类对象的方法,实际能调用子类的覆盖方法的现象叫多态

状态

  • 静态(编译时状态)

  • 动态(运行时状态)

说明

  • 多态调用的方法与对象相关,不与类型相关

  • Python的全部对象都只有"运行时状态(动态)", 没有"C++语言"里的"编译时状态(静态)"

class Shape:def draw(self):print("Shape的draw()被调用")class Point(Shape):def draw(self):print("正在画一个点!")class Circle(Point):def draw(self):print("正在画一个圆!")def my_draw(s):s.draw()  # 此处显示出多态shapes1 = Circle()
shapes2 = Point()
# 调用Circle 类中的draw
my_draw(shapes1)  # 正在画一个圆!
# 调用Point 类中的draw
my_draw(shapes2)  # 正在画一个点!

3、方法重写

果父类方法的功能不能满足需求,可以在子类重写父类的方法

函数重写

在自定义类内添加相应的方法,让自定义类创建的实例像内建对象一样进行内建函数操作

对象转字符串函数重写

str() 函数的重载方法:

  • def __str__(self)
  • 如果没有 __str__(self) 方法,则返回repr(obj)函数结果代替
class MyNumber:"此类用于定义一个自定义的类,用于演示str/repr函数重写"def __init__(self, value):"构造函数,初始化MyNumber对象"self.value = valuedef __str__(self):"转换为普通字符串"return f"{self.value}"n1 = MyNumber("一只猫")
n2 = MyNumber("一只狗")
print(n2)  # 一只狗

内建函数重写

  • __abs__ abs(obj) 函数调用

  • __len__ len(obj) 函数调用

  • __reversed__ reversed(obj) 函数调用

  • __round__ round(obj) 函数调用

算术运算符重载

方法名运算符和表达式说明
__add__(self, rhs)self + rhs加法
__sub__(self, rhs)self - rhs减法
__mul__(self, rhs)self * rhs乘法
__truediv__(self, rhs)self / rhs除法
__floordiv__(self, rhs)self // rhs地板除
__mod__(self, rhs)self % rhs取模(求余)
__pow__(self, rhs)self ** rhs

4、super函数

super() 函数是用于调用父类(超类)的一个方法。

super() 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

super() 方法的语法:

在子类方法中可以使用super().add()调用父类中已被覆盖的方法

可以使用super(Child, obj).myMethod()用子类对象调用父类已被覆盖的方法

"""
钻石继承问题
D B A C
"""
class A:def process(self):print("A process")class B(A):def process(self):print("B process")# 防止子类同名覆盖# A.process(self)  # 手动调用A的process方法super().process()  # 调用super()方法class C(A):def process(self):print("C process")# 防止子类同名覆盖# A.process(self)  # 手动调用A的process方法super().process()  # 调用super()方法class D(B,C):def process(self):print("D process")# 防止子类同名覆盖# B.process(self)  # 手动调用B的process方法# C.process(self)super().process()  # 调用super()方法d = D()
# d.process()  # D B A C A
d.process()  # D B A C
# 在类的属性中使用super()
class Parent:def __init__(self, name):self.name = nameclass Child(Parent):def __init__(self, name, age):super().__init__(name)  # 调用super()方法 则不用写父类名self.age = agedef print_info(self):print(self.name, self.age)child01 = Child("小明",10)
child01.print_info()  # 小明 10

二、迭代器和生成器

1、迭代器

  • 迭代器是访问可迭代对象的工具

  • 迭代器是指用 iter(obj) 函数返回的对象(实例)

  • 迭代器可以用next(it)函数获取可迭代对象的数据

迭代器函数iter和next

函数说明
iter(iterable)从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象
next(iterator)从迭代器iterator中获取下一个记录,如果无法获取一下条记录,则触发 StopIteration 异常

说明

  • 迭代器只能往前取值,不会后退

  • 用iter函数可以返回一个可迭代对象的迭代器

# 可迭代的对象
L = list(range(10))
it = iter(L)
print(next(it))  # 0# try-except 处理异常
while True:try:print(next(it))except:print("迭代结束")break
# 0 1 2 3 4 5 6 7 8 9 迭代结束

2、生成器

生成器和迭代器一样可以配套for循环语句使用。

yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。

  • yield 语句返回的是可迭代对象
  • return 返回的为不可迭代对象

生成器函数

含有yield 语句的函数是生成器函数,此函数调用回返回一个生成器对象,生成器也是可迭代对象

语法:

yield 表达式
def myrange(stop):i = 0while i < stop:yield ii += 1for x in myrange(10):print(x)# 0 1 2 3 4 5 6 7 8 9

生成器表达式

语法

( 表达式 for 变量 in 可迭代对象 [if 真值表达式])
# [] 内容代表可以省略

三、函数式编程

定义:用一系列函数解决问题。

  • 函数可以赋值给变量,赋值后变量绑定函数。

  • 允许将函数作为参数传入另一个函数。

  • 允许函数返回一个函数。

1、函数作为参数

将核心逻辑传入方法体,使该方法的适用性更广。

def fun01():print("fun01函数执行")# a = fun01()  # fun01函数执行def fun02(func):print("fun02函数执行")func()fun02(fun01)  # fun02函数执行 fun01函数执行

总结

1、使用场合

很多的逻辑或者说核心点是不变的,大多数就是一致的,这个时候就可以使用函数式编程思想,可以很好的去定位这个逻辑【函数式编程思想相对于面向对象编程思想,它更接近于算法】。

2、函数式编程&面向对象思想

如果需求中存在多个逻辑变化点时,可以使用类来进行,因为面向对象中存在继承、重写。而函数式编程思想则是将变化点提取到函数中,实现简单的逻辑。

1.1 lambda表达式
# 定义:
变量 = lambda 形参: 方法体# 调用:
变量(实参)

说明

  • 形参没有可以不填
  • 方法体只能有一条语句,且不支持赋值语句
1.2 内置高阶函数

定义:将函数作为参数或返回值的函数。

常用:

(1)map(函数,可迭代对象)

  • 使用可迭代对象中的每个元素调用函数,将返回值作为新可迭代对象元素;返回值为新可迭代对象。

(2)filter(函数,可迭代对象)

  • 根据条件筛选可迭代对象中的元素,返回值为新可迭代对象。

(3)sorted(可迭代对象, key=函数, reverse=True)

  • 排序,返回值为排序后的列表结果。

(4)max(可迭代对象, key = 函数)

  • 根据函数获取可迭代对象的最大值。

(5)min(可迭代对象,key = 函数)

  • 根据函数获取可迭代对象的最小值。

class Gril:list_girl = []  # 类属性 存放信息def __init__(self,name,score,age,height):self.name = nameself.score = scoreself.age = ageself.height = height# print(self)Gril.list_girl.append(self)def __str__(self):return f"{self.name}-{self.score}-{self.age}-{self.height}"girl01 = Gril("阿珂", 100, 23, 168)
girl02 = Gril("苏荃", 92, 32, 170)
girl03 = Gril("双儿", 90, 25, 159)
girl04 = Gril("小郡主", 79, 22, 160)
girl05 = Gril("方怡", 75, 27, 165)
girl06 = Gril("建宁", 86, 25, 163)
girl07 = Gril("曾柔", 67, 24, 158)# print(girl01)
"""
lambda表达式
变量 = lambda 形参: 方法体
"""# 01 打印所有对象的名称
"""
map(函数,可迭代对象)使用可迭代对象中的每个元素调用函数,将返回值作为新可迭代对象元素;返回值为新可迭代对象
"""
for element in map(lambda item: item.name, Gril.list_girl):print(element)
print("---------------")# 02 获取所有颜值大于80的对象
"""
filter(函数,可迭代对象)根据条件筛选可迭代对象中的元素,返回值为新可迭代对象
"""
for element in filter(lambda item: item.score > 80, Gril.list_girl):print(element)
print("---------------")# 03 获取年龄最大的对象
"""
max(可迭代对象, key = 函数)根据函数获取可迭代对象的最大值
"""
print(max(Gril.list_girl, key=lambda item:item.age))
print("---------------")# 04 排序
"""
sorted(可迭代对象, key=函数, reverse=True)排序,返回值为排序后的列表结果
"""
for element in sorted(Gril.list_girl, key=lambda item:item.score, reverse=False):print(element)"""
阿珂
苏荃
双儿
小郡主
方怡
建宁
曾柔
---------------
阿珂-100-23-168
苏荃-92-32-170
双儿-90-25-159
建宁-86-25-163
---------------
苏荃-92-32-170
---------------
曾柔-67-24-158
方怡-75-27-165
小郡主-79-22-160
建宁-86-25-163
双儿-90-25-159
苏荃-92-32-170
阿珂-100-23-168
"""

2、函数作为返回值

2.1 闭包

定义

  • 定义在一个函数内部的函数,同时这个函数又引用了外部的变量。

  • 在本质上,闭包是将内部嵌套函数和函数外部的执行环境绑定在一起的对象。

满足条件:

  • 必须有一个内嵌函数

  • 内嵌函数必须引用外部函数中变量

  • 外部函数返回值必须是内嵌函数。

def func01():a = 1def func02():print(a)return func02re = func01()
re()  # 1
2.2 装饰器

定义

  • 装饰器是一个函数,主要作用是来用包装另一个函数或类

作用

  • 在不修改被装饰的函数的源代码,不改变被装饰的函数的调用方式的情况下添加或改变原函数的功能。

语法

def 装饰器函数名(fn):语句块return 函数对象@装饰器函数名 <换行>
def 被装饰函数名(形参列表):语句块
def print_func_name(func):def wrapper():# 新功能# __name__ 获取函数名 内置属性print(func.__name__)# 旧功能return func()return wrapper# 被装饰器函数
@print_func_name
def func01():print("func01已执行")return "motto"
@print_func_name
def func02():print("func02已执行")func02()  # func02 func02已执行
func01()  # func01 func01已执行

分类

基本装饰器 带参数的装饰器 装饰器链 类装饰器

"""
旧函数 统计值
新函数 功能是打印总执行时间
"""
import time
# 新函数
def all_time(func):def wrapper(*args, **kwargs):# time.time()方法可以获取当前时间start_time = time.time()# 调用旧函数result = func(*args, **kwargs)# 获得结束时间end_time = time.time()print("执行时间:", end_time - start_time)return result# 闭包 返回内部函数return wrapper# 旧函数
@all_time
def func01():sum_value = 0for i in range(100000000):sum_value += ireturn sum_valuefunc01()  # 4.061215400695801# 输入参数的形式
@all_time
def func02(n):sum_value = 0for i in range(n):sum_value += ireturn sum_valuefunc02(1000000000)  # 41.46981358528137

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

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

相关文章

AI 通俗理解强人工智能和弱人工智能

强人工智能&#xff08;Strong AI&#xff09;和弱人工智能&#xff08;Weak AI&#xff09;是两种不同类型的人工智能系统&#xff0c;它们的目标、能力和应用范围有很大的区别。 生活化例子 想象你有两个助手&#xff1a; 弱人工智能助手&#xff1a;你让它查资料、翻译、…

HarmonyOS Next模拟器异常问题及解决方法

1、问题1&#xff1a;Failed to get the device apiVersion. 解决方法&#xff1a;关闭模拟器清除用户数据重启

电子商务网站维护技巧:保持WordPress、主题和插件的更新

在这个快节奏的数字时代&#xff0c;维护一个电子商务网站的首要任务之一是保持WordPress、主题和插件的最新状态。过时的软件不仅可能导致功能故障&#xff0c;还可能带来安全风险。本文将深入探讨如何有效地更新和维护您的WordPress网站&#xff0c;以确保其安全性和性能。 …

【天池比赛】【零基础入门金融风控 Task2赛题理解】【2.3.6】

【天池比赛】【零基础入门金融风控 Task2赛题理解】【2.3.1-2.3.5】 2.3.6 变量分布可视化 2.3.6.1 单一变量分布可视化 对于 pandas.core.series.Series 类型的变量&#xff1a; index&#xff1a;含义&#xff1a;它表示 Series 对象的索引&#xff0c;也就是每个数据点对…

Docker-Consul概述以及集群环境搭建

文章目录 一、Docker consul概述二、consul 部署1.consul服务器2.registrator服务器&#xff08;客户端&#xff09;2.consul-template&#xff08;在consul服务器&#xff09;3.consul 多节点 一、Docker consul概述 容器服务更新与发现&#xff1a;先发现再更新&#xff0c;…

Leetcode 347 Top K Frequent Elements

题意&#xff1a; 求前k个出现频率最高的元素 首先得到一个频率图这是肯定的&#xff0c;下一步要考虑建立一个堆&#xff0c;堆中保存着前k个频率最大的数字&#xff0c;这个怎么做&#xff0c;可以用customized cmp来做&#xff0c;把数字存进去完事儿。注意这里不用 保存所有…

FFmpeg 4.3 音视频-多路H265监控录放C++开发三 :安装QT5.14.2, 并将QT集成 到 VS2019中。

一&#xff0c;安装QT&#xff0c; 重点&#xff1a;在安装QT的时候要安装msvc201x版本的组件&#xff0c; 二 &#xff0c; 安装 qt-vs-tools Index of /development_releases/vsaddin/2.8.1 三&#xff0c;需要安装过 windows10 SDK&#xff0c;一般我们在安装vs2019的时候就…

【MR开发】在Pico设备上接入MRTK3(三)——在Unity中运行MRTK示例

在前面的文档中&#xff0c;介绍了如何在Unity工程中配置号MRTK和Pico SDK 【MR开发】在Pico设备上接入MRTK3&#xff08;一&#xff09;在Unity中导入MRTK3依赖【MR开发】在Pico设备上接入MRTK3&#xff08;二&#xff09;在Unity中配置Pico SDK 本文将介绍如何运行一个简单…

Docker 安装sql server 登陆失败

错误&#xff1a; Sqlcmd: Error: Microsoft ODBC Driver 18 for SQL Server : SSL Provider: [error:0A000086:SSL routines::certificate verify failed:self-signed certificate]. Sqlcmd: Error: Microsoft ODBC Driver 18 for SQL Server : Client unable to establish co…

【virtuoso】sp测电阻

电路测量原理&#xff1a; 1. 电路原理图 2. 仿真设置 点击select&#xff0c;在原理图选择port设置sp扫频范围 3. plot图像 3.1 plot电阻图像 由公式可得&#xff0c;电阻值为阻抗的实部&#xff0c;所以 1. 选择 ZP 2. 绘制real 3. 点击Z11 4. 即可看到电阻值 3.2 plot电容图…

C++第七讲:STL--list的使用及模拟实现

C第七讲&#xff1a;STL--list的使用及模拟实现 1.list的使用1.1list是什么1.2构造、析构、赋值运算符重载1.3迭代器1.4empty、size、max_size1.5front、back1.6assign -- 代替1.7push_back和emplace_back1.8emplace1.9insert、erase、swap、resize、clear1.10find1.11splice1.…

CSDN Markdown 编辑器语法大全

Markdown 是一种轻量级标记语言&#xff0c;它以简洁、易读易写的特点&#xff0c;被广泛应用于技术文档、博客文章、笔记等领域。CSDN 的 Markdown 编辑器为用户提供了丰富的功能&#xff0c;让用户能够轻松地创建格式规范、内容丰富的文档。以下是一份详细的 CSDN Markdown 编…

大数据治理--法规遵从与隐私保护

目录 ​编辑一、国际及地方数据保护法规 1.1 国际数据保护法规 1.1.1 欧盟《通用数据保护条例》&#xff08;GDPR&#xff09; 1.1.2 美国《加州消费者隐私法案》&#xff08;CCPA&#xff09; 1.1.3 中国《网络安全法》及《个人信息保护法》 1.2 地方数据保护法规 二、…

KClass-关于kotlin中的反射

override val responseType: KClass<SetOperationModeResponse> SetOperationModeResponse::class,这段代码的含义&#xff1a; responseType 是一个只读属性&#xff08;val&#xff09;&#xff0c;它的类型是 KClass<SetOperationModeResponse>。KClass<T&…

深入解析缓存技术

文章目录 1. 缓存基本原理2. 缓存更新机制2.1 Cache Aside模式2.2 Read/Write Through2.3 Write Behind Caching2.4 对比总结 3. 缓存数据过期策略3.1 最近最少使用&#xff08;Least Recently Used, LRU&#xff09;算法3.2 先进先出&#xff08;First-In-First-Out, FIFO&…

OpenCV高级图形用户界面(10)创建一个新的窗口函数namedWindow()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 创建一个窗口。 函数 namedWindow 创建一个可以作为图像和跟踪条占位符的窗口。创建的窗口通过它们的名字来引用。 如果已经存在同名的窗口&am…

linux线程 | 全面理解同步与互斥 | 同步

前言&#xff1a;本节内容主要讲解linux下的同步问题。 同步问题是保证数据安全的情况下&#xff0c;让我们的线程访问具有一定的顺序性。 线程安全就规定了它必须是在加锁的场景下的&#xff01;&#xff01;那么&#xff0c; 具体什么是同步问题&#xff0c; 我们加下来看看吧…

lesson01 Backtrader是什么

[Backtrader]专题连载 Backtrader是什么&#xff1f; Backtrader 是 2015 年开源的 Python 量化回测框架&#xff08;支持实盘交易&#xff09;。专注于为量化交易策略提供回测和实盘交易功能。它允许用户集中精力编写可复用的交易策略、指标和分析工具&#xff0c;而无需花费…

使用 Python 解析火狐浏览器的 SQLite3 数据库

使用 Python 解析火狐浏览器的 SQLite3 数据库 火狐浏览器&#xff08;Firefox&#xff09;使用 SQLite3 数据库来存储用户的各种数据&#xff0c;如书签、历史记录和下载记录等。在这篇文章中&#xff0c;我们将学习如何使用 Python 来解析这些 SQLite3 数据库。 准备工作 …

衡石分析平台系统分析人员手册-可视化报表仪表盘

仪表盘​ 仪表盘是数据分析最终展现形式&#xff0c;是数据分析的终极展现。 应用由一个或多个仪表盘展示&#xff0c;多个仪表盘之间有业务关联。 仪表盘编辑​ 图表列表​ 打开仪表盘后&#xff0c;就会看到该仪表盘中所有的图表。 调整图表布局​ 将鼠标移动到图表上拖动…