Python学习笔记9:魔法方法、特性和迭代器

news/2024/4/26 3:49:06/文章来源:https://blog.csdn.net/qq_36333986/article/details/129251792

魔法方法、特性和迭代器

构造函数

重写构造函数时,必须调用超类(继承的类)的构造函数,否则可能无法正确地初始化对象

class Bird: def __init__(self): self.hungry = True def eat(self): if self.hungry: print('Aaaah ...') self.hungry = False else: print('No, thanks!')# 子类SongBird, SongBird没有属性hungry
class SongBird(Bird): def __init__(self): self.sound = 'Squawk!' def sing(self): print(self.sound)>>> sb = SongBird() 
>>> sb.sing() 
Squawk!
>>> sb.eat() 
Traceback (most recent call last): File "<stdin>", line 1, in ? File "birds.py", line 6, in eat if self.hungry: 
AttributeError: SongBird instance has no attribute 'hungry'
class SongBird(Bird): def __init__(self): super().__init__()self.sound = 'Squawk!' def sing(self): print(self.sound)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wNGwaOIZ-1677508665299)(./resource/super%E4%BC%98%E7%82%B9.png)]

元素访问

序列和映射基本上是元素(item)的集合,要实现它们的基本行为(协议),不可变对象需要实现2个方法,而可变对象需要实现4个

  • __len__(self)
  • __getitem__(self, key)
  • __setitem__(self, key, value)
  • __delitem__(self, key)

对于这些方法,还有一些额外的要求。

  • 对于序列,如果键为负整数,应从末尾往前数。换而言之,x[-n]应与x[len(x)-n]等效。
  • 如果键的类型不合适(如对序列使用字符串键),可能引发TypeError异常。
  • 对于序列,如果索引的类型是正确的,但不在允许的范围内,应引发IndexError异常。

特性

  1. 函数property
class Rectangle: def __init__ (self): self.width = 0 self.height = 0 def set_size(self, size): self.width, self.height = size def get_size(self): return self.width, self.height size = property(get_size, set_size)>>> r = Rectangle() 
>>> r.width = 10 
>>> r.height = 5 
>>> r.size 
(10, 5) 
>>> r.size = 150, 100 
>>> r.width 
150

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wOqhk63y-1677508665301)(./resource/property%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86.png)]

  1. 静态方法和类方法
class MyClass: def smeth(): print('This is a static method') smeth = staticmethod(smeth) def cmeth(cls): print('This is a class method of', cls) cmeth = classmethod(cmeth)# 使用装饰器
class MyClass: @staticmethoddef smeth(): print('This is a static method') @classmethoddef cmeth(cls): print('This is a class method of', cls) 

可指定一个或多个装饰器,为此可在方法(或函数)前面使用运算符@列出这些装饰器(指定了多个装饰器时,应用的顺序与列出的顺序相反

  1. __getattr____setattr__等方法
  • __getattribute__(self, name):在属性被访问时自动调用(只适用于新式类)。
  • __getattr__(self, name):在属性被访问而对象没有这样的属性时自动调用。
  • __setattr__(self, name, value):试图给属性赋值时自动调用。
  • __delattr__(self, name):试图删除属性时自动调用。
class Rectangle: def __init__ (self): self.width = 0 self.height = 0 def __setattr__(self, name, value): if name == 'size': self.width, self.height = value else: self. __dict__[name] = value def __getattr__(self, name): if name == 'size': return self.width, self.height else: raise AttributeError()
  • __dict__属性是一个字典,其中包含所有的实例属性。之所以使用它而不是执行常规属性赋值,是因为旨在避免再次调用__setattr__,进而导致无限循环

  • 编写__getattribute__时亦如此。由于它拦截对所有属性的访问(在新式类中),因此将拦截对__dict__的访问!在__getattribute__中访问当前实例的属性时,唯一安全的方式是使用超类的方法__getattribute__(使用super)。

迭代器

方法__iter__返回一个迭代器,它是包含方法__next__的对象,而调用这个方法时可不提供任何参数

class Fibs: def __init__(self): self.a = 0 self.b = 1 def __next__(self): self.a, self.b = self.b, self.a + self.b return self.a def __iter__(self): return self>>> fibs = Fibs()
>>> for f in fibs: 
... if f > 1000: 
... print(f) 
... break 
... 
1597

通过对可迭代对象调用内置函数iter,可获得一个迭代器

>>> it = iter([1, 2, 3]) 
>>> next(it) 
1 
>>> n

从迭代器创建序列

class TestIterator: value = 0 def __next__(self): self.value += 1 if self.value > 10: raise StopIteration return self.value def __iter__(self): return self >>> ti = TestIterator() 
>>> list(ti) 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

生成器

  1. 创建生成器
def flatten(nested): for sublist in nested: for element in sublist: yield element>>> nested = [[1, 2], [3, 4], [5]] 
>>> for num in flatten(nested): 
...     print(num)
1 
2 
3 
4 
5

生成器不是使用return返回一个值,而是可以生成多个值,每次一个。每次使用yield生成一个值后,函数都将冻结,即在此停止执行,等待被重新唤醒。被重新唤醒后,函数将从停止的地方开始继续执行

  1. 递归式生成器
def flatten(nested): try: for sublist in nested: for element in flatten(sublist): yield element except TypeError: yield nested
  • 基线条件 在基线条件下,要求这个函数展开单个元素(如一个数)。在这种情况下,for循环将引发TypeError异常(因为你试图迭代一个数),而这个生成器只生成一个元素。

  • 递归条件 递归调用flatten(sublist)

如果nested是字符串或类似于字符串的对象,它就属于序列,因此不会引发TypeError异常,可你并不想对其进行迭代

# 要检查对象是否类似于字符串,最简单、最快捷的方式是,尝试将对象与一个字符串拼接起来,并检查这是否会引发TypeError异常①。def flatten(nested): try: # 不迭代类似于字符串的对象:try: nested + '' except TypeError: pass else: raise TypeError for sublist in nested:for element in flatten(sublist): yield element except TypeError: yield nested>>> list(flatten(['foo', ['bar', ['baz']]])) 
['foo', 'bar', 'baz']
  1. 通用的生成器

生成器由两个单独的部分组成:生成器的函数和生成器的迭代器。生成器的函数是由def语句定义的,其中包含yield。

>>> def simple_generator(): yield 1 
... 
>>> simple_generator 
<function simple_generator at 153b44> 
>>> simple_generator() 
<generator object at 1510b0>

对于生成器的函数返回的迭代器,可以像使用其他迭代器一样使用它。

  1. 生成器的方法

在生成器开始运行后,可使用生成器和外部之间的通信渠道向它提供值。这个通信渠道包含如下两个端点

  • 外部世界 外部世界可访问生成器的方法send,这个方法类似于next,但接受一个参数(要发送的“消息”,可以是任何对象)。

  • 生成器 在挂起的生成器内部,yield可能用作表达式而不是语句。换而言之,当生成器重新运行时,yield返回一个值——通过send从外部世界发送的值。如果使用的是next,yield将返回None。

def repeater(value): while True: new = (yield value) if new is not None: value = new>>> r = repeater(42) 
>>> next(r) 
42 
>>> r.send("Hello, world!") 
"Hello, world!"
  • 方法throw
  • 方法close
  1. 模拟生成器
def flatten(nested): result = []                             # 1try: # 不迭代类似于字符串的对象:try: nested + '' except TypeError: pass else: raise TypeError for sublist in nested: for element in flatten(sublist): result.append(element)      # 2except TypeError: result.append(nested)               # 3-1return result                           # 3-2

小结

魔法方法:Python中有很多特殊方法,其名称以两个下划线开头和结尾。这些方法的功能
各不相同,但大都由Python在特定情况下自动调用。例如__init__是在对象创建后调用的。

构造函数:很多面向对象语言中都有构造函数,对于你自己编写的每个类,都可能需要
为它实现一个构造函数。构造函数名为__init__,在对象创建后被自动调用。

重写:类可重写其超类中定义的方法(以及其他任何属性),为此只需实现这些方法即可。
要调用被重写的版本,可直接通过超类调用未关联版本(旧式类),也可使用函数super
来调用(新式类)。

序列和映射:要创建自定义的序列或映射,必须实现序列和映射协议指定的所有方法,
其中包括__getitem__和__setitem__等魔法方法。通过从list(或UserList)和dict(或
UserDict)派生,可减少很多工作量。

迭代器:简单地说,迭代器是包含方法__next__的对象,可用于迭代一组值。没有更多的
值可供迭代时,方法__next__应引发StopIteration异常。可迭代对象包含方法__iter__,
它返回一个像序列一样可用于for循环中的迭代器。通常,迭代器也是可迭代的,即包含
返回迭代器本身的方法__iter__。

生成器:生成器的函数是包含关键字yield的函数,它在被调用时返回一个生成器,即一
种特殊的迭代器。要与活动的生成器交互,可使用方法send、throw和close。

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

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

相关文章

钉钉产品体验报告

一、调研的目的了解企业社交软件&#xff0c;借写竞品分析来帮助自己整理思路&#xff0c;看清市场的发展趋势&#xff1b;体验这类企业设计软件&#xff0c;掌握产品核心业务流程和产品结构&#xff0c;把握需求对应的功能点和界面结构&#xff0c;并侧面了解用户习惯&#xf…

用Python做数据分析有哪些优势?

众所周知&#xff0c;可以用作数据分析的语言有很多&#xff0c;包含Python、R语言等&#xff0c;而且Python被誉为数据分析的一大利器&#xff0c;更是该领域的首选语言&#xff0c;那么用Python做数据分析有哪些优势呢?跟着蛋糕往下看。 第一、Python语言自身的优势 Pytho…

ShardingSphere水平、垂直分库、分表和公共表

目录一、ShardingSphere简介二、ShardingSphere-分库分表1、垂直拆分&#xff08;1&#xff09;垂直分库&#xff08;2&#xff09;垂直分表2、水平拆分&#xff08;1&#xff09;水平分库&#xff08;2&#xff09;水平分表三、水平分库操作1、创建数据库和表2、配置分片的规则…

BigGAN

1、BIGGAN 解读1.1、作者 Andrew Brock、Jeff Donahue、Karen Simonyan 1.2、摘要 尽管最近在生成图像建模方面取得了进展&#xff0c;但从 ImageNet 等复杂数据集中 成功生成高分辨率、多样化的样本仍然是一个难以实现的目标。为此&#xff0c;我们以迄 今为止最大的规模训练生…

fastadmin:在新增页面,打开弹窗单选,参数回传

样式&#xff1a;核心代码&#xff1a;一、弹窗的控制器中&#xff1a;// 定义一个公共函数select()&#xff0c;如果这个请求是Ajax&#xff0c;则返回index()函数&#xff0c;否则返回view对象的fetch()函数。 public function select() {if ($this->request->isAjax(…

【软件测试】测试老鸟的迷途,进军高级自动化测试测试......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 很多从业几年的选手…

【阿旭机器学习实战】【37】电影推荐系统---基于矩阵分解

【阿旭机器学习实战】系列文章主要介绍机器学习的各种算法模型及其实战案例&#xff0c;欢迎点赞&#xff0c;关注共同学习交流。 电影推荐系统 目录电影推荐系统1. 问题介绍1.1推荐系统矩阵分解方法介绍1.2 数据集&#xff1a;ml-100k2. 推荐系统实现2.1 定义矩阵分解函数2.2 …

消息中间件的概念

中间件(middleware)是基础软件的一大类&#xff0c;属于可复用的软件范畴。中间件在操作系统软件&#xff0c;网络和数据库之上&#xff0c;应用软件之下&#xff0c;总的作用是为处于自己上层的应用软件提供运行于开发的环境&#xff0c;帮助用户灵活、高效的开发和集成复杂的…

ICA简介:独立成分分析

1. 简介 您是否曾经遇到过这样一种情况&#xff1a;您试图分析一个复杂且高度相关的数据集&#xff0c;却对信息量感到不知所措&#xff1f;这就是独立成分分析 (ICA) 的用武之地。ICA 是数据分析领域的一项强大技术&#xff0c;可让您分离和识别多元数据集中的底层独立来源。 …

PPP简介,PPP分层体系架构,PPP链路建立过程及PPP的帧格式

PPP&#xff08;Point-to-Point Protocol&#xff09;是一种用于在两个网络节点之间传输数据的通信协议。它最初是为在拨号网络上进行拨号连接而开发的&#xff0c;现在已经被广泛应用于各种网络环境中&#xff0c;例如在宽带接入、虚拟专用网&#xff08;VPN&#xff09;等场景…

【JAVA】一个项目如何预先加载数据?

这里写目录标题需求实现AutowiredPostConstruct实例CommandLineRunner实例ApplicationListener实例参考需求 一般我们可能会有一些在应用启动时加载资源的需求&#xff0c;局部或者全局使用&#xff0c;让我们来看看都有哪些方式实现。 实现 Autowired 如果是某个类里需求某…

[1]MyBatis+Spring+SpringMVC+SSM整合

一、MyBatis 1、MyBatis简介 1.1、MyBatis历史 MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投Google Code旗下&#xff0c; iBatis3.x正式更名为MyBatis。代码于2013年11月迁移到Github。…

Vue中如何利用websocket实现实时通讯

首先我们可以先做一个简单的例子来学习一下简单的websocket模拟聊天对话的功能 原理很简单&#xff0c;有点像VUE中的EventBus&#xff0c;用emit和on传来传去 首先我们可以先去自己去用node搭建一个本地服务器 步骤如下 1.新建一个app.js&#xff0c;然后创建pagejson.js文…

【Linux】-- POSIX信号量

目录 POSIX信号量 sem_init - 初始化信号量 sem_destroy - 销毁信号量 sem_wait - 等待信号量&#xff08;P操作&#xff09; 基于环形队列的生产消费模型 数据结构 - 环形结构 实现原理 POSIX信号量 #问&#xff1a;什么是信号量&#xff1f; 1. 共享资源 -> 任何一…

【笔记】两台1200PLC进行S7 通信(1)

使用两台1200系列PLC进行S7通信&#xff08;入门&#xff09; 文章目录 目录 文章目录 前言 一、通信 1.概念 2.PLC通信 1.串口 2.网口 …

时间颗粒度选择(通过选择时间范围和颗粒度展示选项)

<template><div><el-time-selectplaceholder"起始时间"v-model"startTime":picker-options"startPickerOptions"change"changeStartTime"></el-time-select><el-time-selectplaceholder"结束时间&quo…

想招到实干派程序员?你需要这种面试法

技术招聘中最痛的点其实是不精准。技术面试官或CTO们常常会向我们吐槽&#xff1a; “我经常在想&#xff0c;能不能把我们项目中的代码打印出来&#xff0c;作为候选人的面试题的一部分&#xff1f;” “能不能把一个Bug带上环境&#xff0c;让候选人来试试怎么解决&#xf…

mysql中用逗号隔开的字段作查询用(find_in_set的使用)

mysql中用逗号隔开的字段作查询用(find_in_set的使用) 场景说明 在工作中&#xff0c;经常会遇到一对多的关系。想要在mysql中保存这种关系&#xff0c;一般有两种方式&#xff0c;一种是建立一张中间表&#xff0c;这样一条id就会存在多条记录。或者采用第二种方式&#xff…

【数据结构必会基础】关于树,你所必须知道的亿些概念

目录 1.什么是树 1.1浅显的理解树 1.2 数据结构中树的概念 2.树的各种结构概念 2.1 节点的度 2.2 根节点/叶节点/分支节点 2.3 父节点/子节点 2.4祖先节点/子孙节点 2.5兄弟节点 2.6树的度 2.7节点的层次 2.8森林 3. 如何用代码表示一棵树 3.1链式结构 3.1.1 树节…

Gitea Windows环境下服务搭建

前言&#xff1a;这篇文章没有去分析各大平台的优劣势&#xff0c;仅教学大家搭建一个属于自己的git代码管理器&#xff0c;主要作用在局域网内&#xff0c;办公电脑搭建一个简单的Gitea代码管理器。数据库使用SQLite3&#xff0c;环境是windows10。如果不是这个环境的话&#…