当前位置: 首页 > news >正文

Python 类对象

Python 类对象

经典迭代器

  • 可迭代对象的定义: 使用内置的iter可以获取迭代器的对象。如果对象实现了能返回迭代器的__iter__方法,那么对象就是可迭代的。序列都可以迭代。实现了__getitem__方法,而且接受从0开始的索引,这种对象也是可以迭代的。

  • 可迭代对象与迭代器之间的关系:Python从可迭代对象中获取迭代器。

import re
import reprlibRE_WORD = re.compile(r'\w+')class SentenceV2:def __init__(self, text):self.text = textself.words = RE_WORD.findall(text)def __repr__(self):return f'Sentence({reprlib.repr(self.text)})'def __iter__(self):# 返回一个迭代器return SentenceIterator(self.words)class SentenceIterator:def __init__(self, words):self.words = words  # 初始化索引self.index = 0def __next__(self):try:word = self.words[self.index]except IndexError:raise StopIteration()self.index += 1return worddef __iter__(self):  return self
  • 可迭代对象有一个__iter__方法,每次都实例化一个新迭代器。
  • 迭代器要实现__next__方法,返回单个元素,此外还要实现__iter__方法,返回迭代器本身。
  • 迭代器也是可迭代对象,但是可迭代对象不是迭代器。
生成器函数
import re
import reprlibRE_WORD = re.compile(r'\w+')class SentenceV3:def __init__(self, text):self.text = textself.words = RE_WORD.findall(text)def __repr__(self):return 'Sentence(%s)' % reprlib.repr(self.text)def __iter__(self):for word in self.words:# 产生当前的wordyield wordclass ArithmeticProgression:def __init__(self, begin, step, end=None):self.begin = beginself.step = stepself.end = end  # None -> "infinite" seriesdef __iter__(self):result_type = type(self.begin + self.step)result = result_type(self.begin)forever = self.end is Nonewhile forever or result < self.end:yield resultresult += self.step

只要Python函数的主体中有yield关键字,该函数就是生成器函数。调用生成器函数,返回一个生成器对象。

生成器工作原理:

  1. 生成器函数创建一个生成器对象,包装生成器函数的主体。
  2. 把生成器对象传给next()函数时,生成器函数提前执行函数主体中的下一个yield语句,返回产出的值,并在函数主体的当前位置暂停。
  3. 函数的主体返回时,Python创建的外层生成器对象抛出StopIteration异常。

上下文管理器

import sysclass LookingGlass:def __enter__(self):self.original_write = sys.stdout.write# 打上猴子补丁sys.stdout.write = self.reverse_writereturn 'JABBERWOCKY'def reverse_write(self, text):# 反转参数的内容self.original_write(text[::-1])def __exit__(self, exc_type, exc_value, traceback):# 将原来的方法还原sys.stdout.write = self.original_writeif exc_type is ZeroDivisionError:print('Please DO NOT divide by zero!')return True

image-20240624090216546

Vector2d

from array import array 
import math class Vector2d: typecode = 'd'  def __init__(self, x, y): self.x = float(x)    self.y = float(y) # 可以解包 v = Vector2d(2,2)# x,y = vdef __iter__(self): return (i for i in (self.x, self.y))  # print返回def __repr__(self): class_name = type(self).__name__ return '{}({!r}, {!r})'.format(class_name, *self)  def __str__(self): # 调用__iter__return str(tuple(self))  def __bytes__(self): return (bytes([ord(self.typecode)]) +  bytes(array(self.typecode, self)))  # 判断Vector2d是否相等def __eq__(self, other): return tuple(self) == tuple(other) def __abs__(self): return math.hypot(self.x, self.y)def __bool__(self): return bool(abs(self))  

格式化显示

>>> format(42, 'b') 
'101010' 
>>> format(2 / 3, '.1%') 
'66.7%'
# datetime类重构了__format__方法
>>> from datetime import datetime 
>>> now = datetime.now() 
>>> format(now, '%H:%M:%S') 
'18:49:05' 
>>> "It's now {:%I:%M %p}".format(now) 
"It's now 06:49 PM"
 def __format__(self, fmt_spec=''): components = (format(c, fmt_spec) for c in self)  return '({}, {})'.format(*components)  
>>> v1 = Vector2d(3, 4) 
>>> format(v1) 
'(3.0, 4.0)' 
>>> format(v1, '.2f') 
'(3.00, 4.00)' 
>>> format(v1, '.3e') 
'(3.000e+00, 4.000e+00)'

可哈希的

为了把 Vector2d 实例变成可哈希的,必须实现 hash 方法 (还需要 eq 方法,前面已经实现了)。此外,还要让向量实例 不可变

class Vector2d: typecode = 'd' def __init__(self, x, y): self.__x = float(x)  self.__y = float(y) @property  def x(self): return self.__x @property  def y(self): return self.__y def __hash__(self): return hash((self.x, self.y))

使用 slots 节省空间

默认情况下,Python 把各个实例的属性存储在一个名为 dict 的字典中字典消耗的内存很多。但是,如果定义一个名为 slots 的类属性,以序列的形式 存储属性名称,那么 Python 将使用其他模型存储实例属性: slots 中的属性名称存储在一个隐藏的引用数组中,消耗的内 存比字典少。

>>> class Pixel: 
...     __slots__ = ('x', 'y')  
... 
>>> p = Pixel()  
>>> p.__dict__  
Traceback (most recent call last): ... 
AttributeError: 'Pixel' object has no attribute '__dict__' 
>>> p.x = 10 
>>> p.y = 20 
# 不允许添加其他属性
>>> p.color = 'red' 
Traceback (most recent call last): ... 
AttributeError: 'Pixel' object has no attribute 'color'

Vector

多维向量

>>> Vector([3.1, 4.2]) 
Vector([3.1, 4.2]) 
>>> Vector((3, 4, 5)) 
Vector([3.0, 4.0, 5.0]) 
>>> Vector(range(10)) 
Vector([0.0, 1.0, 2.0, 3.0, 4.0, ...])
from array import array 
import reprlib 
import math class Vector: typecode = 'd' def __init__(self, components): self._components = array(self.typecode, components) def __iter__(self): return iter(self._components) def __repr__(self): # 替换为省略号# 返回array('d', [0.0, 1.0, 2.0, 3.0, 4.0, ...])components = reprlib.repr(self._components)  components = components[components.find('['):-1]  return f'Vector({components})' def __str__(self): return str(tuple(self)) def __bytes__(self): return (bytes([ord(self.typecode)]) + bytes(self._components)) # 调用len()返回def __len__(self): return len(self._components) def __eq__(self, other): if len(self) != len(other): return False for a, b in zip(self, other): if a != b:  return False return True  def __abs__(self): return math.hypot(*self) def __bool__(self): return bool(abs(self))

切片

    def __getitem__(self, index): return self._components[index]
>>> v1 = Vector([3, 4, 5]) 
>>> len(v1) 
3 
>>> v1[0], v1[-1] 
(3.0, 5.0) 
>>> v7 = Vector(range(7)) 
# 返回的是array
>>> v7[1:4] 
array('d', [1.0, 2.0, 3.0])
def __getitem__(self, key): # 调用Vector[a:b:c] 传入的是slice(a,b,c)if isinstance(key, slice): cls = type(self)  return cls(self._components[key]) # 调用Vector[a]index = operator.index(key)  return self._components[index]  

动态存取属性

# 希望xyzt能获取前4个元素
>>> v = Vector(range(10)) 
>>> v.x 
0.0 
>>> v.y, v.z, v.t 
(1.0, 2.0, 3.0)
 __match_args__ = ('x', 'y', 'z', 't')  def __getattr__(self, name): cls = type(self)  try: pos = cls.__match_args__.index(name)  except ValueError: pos = -1 if 0 <= pos < len(self._components): return self._components[pos] msg = f'{cls.__name__!r} object has no attribute {name!r}'  raise AttributeError(msg)
>>> a = Vector(range(9))
>>> a
Vector([0.0, 1.0, 2.0, 3.0, 4.0, ...])
>>> a.x
0.0
>>> a.y
1.0
# x不应该可以直接复制,这样会创建一个x变量
>>> a.x = 10
>>> a
Vector([0.0, 1.0, 2.0, 3.0, 4.0, ...])
>>> a.x
10
>>> 
 # 赋值操作def __setattr__(self, name, value): cls = type(self) if len(name) == 1:  if name in cls.__match_args__:  error = 'readonly attribute {attr_name!r}' elif name.islower():  error = "can't set attributes 'a' to 'z' in 
{cls_name!r}" else: error = ''  if error:  msg = error.format(cls_name=cls.__name__, 
attr_name=name) raise AttributeError(msg) # 没问题就调用父类方法super().__setattr__(name, value)  

哈希

 def __hash__(self): hashes = (hash(x) for x in self._components) # reduce类似于递归函数,sum、any 和 all的本质都是调用reducereturn functools.reduce(operator.xor, hashes, 0) 
     msg = error.format(cls_name=cls.__name__, 

attr_name=name)
raise AttributeError(msg)
# 没问题就调用父类方法
super().setattr(name, value)


### 哈希```pythondef __hash__(self): hashes = (hash(x) for x in self._components) # reduce类似于递归函数,sum、any 和 all的本质都是调用reducereturn functools.reduce(operator.xor, hashes, 0) 

相关文章:

Python 类对象

Python 类对象 经典迭代器 可迭代对象的定义&#xff1a; 使用内置的iter可以获取迭代器的对象。如果对象实现了能返回迭代器的__iter__方法&#xff0c;那么对象就是可迭代的。序列都可以迭代。实现了__getitem__方法&#xff0c;而且接受从0开始的索引&#xff0c;这种对象也…...

pytest unittest temp path单元测试创建临时文件

参考了这个&#xff1a;Test Files Creating a Temporal Directory in Python Unittests | Simple IT &#x1f918; Rocks 并使用pathlib做了优化&#xff1a; import tempfile import unittest from pathlib import Pathclass TestExample(unittest.TestCase):def test_exa…...

在线样机生成器,制作精美的电脑手机壁纸图片展示

在线样机生成器&#xff0c;可以制作精美的电脑手机壁纸图片展示。在线样机生成器支持不同的模型如浏览器、手机、笔记本电脑、手表等结合使用&#xff0c;帮助用户快速生成样机展示图片。下面小编就来和大家分享一款免费的在线样机生成器-壁纸样机生成器。 壁纸样机生成器是一…...

FreeRTOS实时操作系统

1.认识实施操作系统 1.1 裸机和实时操作系统 裸机&#xff1a; 早期嵌入式开发没有嵌入式操作系统的概念&#xff0c;直接操作裸机&#xff0c;在裸机上写程序&#xff0c;比如用51单片机基本就没有操作系统的概念。 通常把程序设计为前后台系统&#xff0c;主要分为两部分&a…...

C/S、B/S架构(详解)

一、CS、BS架构定义 CS架构&#xff08;Client-Server Architecture&#xff09;是一种分布式计算模型&#xff0c;其中客户端和服务器之间通过网络进行通信。在这种架构中&#xff0c;客户端负责向服务器发送请求&#xff0c;并接收服务器返回的响应。服务器则负责处理客户端的…...

代码随想录算法训练营第六十五天|KM99. 岛屿数量——深搜、KM99. 岛屿数量——广搜、KM100. 岛屿的最大面积

代码随想录算法训练营第六十五天 KM99. 岛屿数量——深搜 题目链接&#xff1a;KM99. 岛屿数量 使用递归深度搜索&#xff0c;将每次遇到的岛屿上下左右记录为已经到过&#xff0c;如果遇到没到过的说明它上下左右不是之间遍历过的岛屿&#xff0c;结果计数1。最后统计计数即…...

Lua 面向对象编程

Lua 面向对象编程 Lua 是一种轻量级的编程语言,通常用于嵌入应用程序中,提供灵活的扩展和定制功能。尽管 Lua 本身是一种过程式语言,但它提供了强大的元机制,允许开发者实现面向对象的编程范式。本文将探讨 Lua 中的面向对象编程(OOP)概念、实现方式以及最佳实践。 面向…...

AI赋能前端:你的Chrome 控制台需要AI(爱)

像会永生那样去学习,像明天就要死亡那样去生活。——圣雄甘地 大家好,我是柒八九。一个专注于前端开发技术/Rust及AI应用知识分享的Coder 此篇文章所涉及到的技术有 AI(Gemini)ChromeDevTool🪜魔法接码平台因为,行文字数所限,有些概念可能会一带而过亦或者提供对应的学习…...

代码随想录-Day38

509. 斐波那契数 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 …...

CSS阴影优化气泡框样式

<body> <div class"pop">气泡框</div> </body>body{display: flex;justify-content: center;align-items: center;height: 100% } .pop{display: flex;justify-content: center;align-items: center;background: #409eff;width: 150px;heigh…...

强化安全新篇章:韶关石油化工可燃气体报警器年检解析

韶关&#xff0c;这座位于广东省北部的城市&#xff0c;近年来在石油化工行业取得了显著的发展。 随着一批批大型石化企业的进驻和投产&#xff0c;韶关不仅成为了区域性的石化产业基地&#xff0c;也为地方经济带来了强劲的增长动力。 然而&#xff0c;随着石化产业的快速发…...

Centos7 Docker部署PgSQL

拉取镜像 docker pull postgres:14.7运行容器 docker run --restartalways --nethost --shm-size"2g" --name pgsql -v /home/postgresql/data/pgdata:/var/lib/postgresql/data -v /etc/localtime:/etc/localtime -e POSTGRES_PASSWORDtest2023 -d postgres:14…...

LeetCode:经典题之21、24 题解及延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 …...

【C++11】initializer_list详解!

一、什么是initializer_list? nitializer_list 是一种C11新的类型特性&#xff0c;它允许我们以统一的方式初始化对象。它是一个代表数组的轻量级包装器&#xff0c;通常用于构造函数和函数参数中&#xff0c;以允许传递一个初始化元素列表。 initializer_list也是一种模板类…...

如何在Java中处理UnsupportedOperationException异常?

如何在Java中处理UnsupportedOperationException异常&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在Java编程中&#xff0c;我们经常会遇到各…...

WPS没保存关闭了怎么恢复数据?4个方法(更新版)

想象一下&#xff0c;你正在用WPS奋笔疾书&#xff0c;灵感如泉水般涌出&#xff0c;突然间&#xff0c;电脑却跟你开了个玩笑——啪地一下&#xff0c;文档未保存就关闭了&#xff01;是不是感觉像是被泼了一盆冷水&#xff0c;所有的热情瞬间熄灭&#xff1f;别急&#xff0c…...

elementplus el-table(行列互换)转置

Element Plus v2.4.0, repl v3.4.0 <template> <div><el-table :data"tableData" style"width: 100%"><el-table-column prop"name" label"名字" width"180" /><el-table-column prop"wei…...

Gradle 核心之 Task

一、前言 只有 Task 才可以在 Gradle 的执行阶段去执行&#xff08;其实质是执行的 Task 中的一系列 Action&#xff09;&#xff0c;所以 Task 的重要性不言而喻。 二、Task 2.1 Task 定义与配置 Task 的定义方式有如下两种&#xff1a; Task 的配置方式也有如下两种&#xf…...

【React 】折叠面板,点击展开时再请求数据

需求背景&#xff1a;使用折叠面板的形式展示数据&#xff0c;面板内部数据需要在打开时请求接口获取。 遇到问题&#xff1a;最开始使用Antd 的折叠面板组件&#xff0c;它对于数据直接渲染是没问题的&#xff0c;但是不好满足打开面板时再动态加载数据的需求&#xff0c;于是…...

c++学习 文件操作,模板

文件操作 #include<iostream> #include<string> #include<fstream> using namespace std; //文本操作 //程序运行时产生的数据都属于临时数据&#xff0c;程序一旦运行结束都会被释放 //通过文件可以数据持久化 //c中对文件操作包含头文件<fstream> /…...

嵌入式系统中SipHash轻量级哈希实现与优化

1. SipHash 嵌入式底层实现技术解析SipHash 是一种基于加法-循环-异或&#xff08;Add-Rotate-Xor, ARX&#xff09;结构的伪随机函数族&#xff0c;专为短输入消息设计&#xff0c;在嵌入式系统中广泛用于哈希表键值保护、拒绝服务&#xff08;DoS&#xff09;防护、安全计数器…...

泛微E8流程管理进阶:从数据库角度理解流程状态与节点关系

泛微E8流程管理进阶&#xff1a;从数据库角度理解流程状态与节点关系 在企业的数字化转型浪潮中&#xff0c;流程管理系统扮演着越来越重要的角色。作为国内领先的协同办公平台&#xff0c;泛微E8凭借其强大的流程引擎和灵活的定制能力&#xff0c;成为众多企业的首选。然而&am…...

7个技巧彻底改变你的Mac菜单栏体验:Ice终极配置指南

7个技巧彻底改变你的Mac菜单栏体验&#xff1a;Ice终极配置指南 【免费下载链接】Ice Powerful menu bar manager for macOS 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice Ice是一款强大的macOS菜单栏管理工具&#xff0c;专门帮助用户整理杂乱的菜单栏图标&…...

共享店铺模式小程序开发方案

共享店铺模式是一种将线下实体店铺资源通过数字化手段进行整合与共享的商业模式&#xff0c;小程序作为轻量级应用非常适合实现这一目标。以下是开发共享店铺模式小程序的关键要点&#xff1a;核心功能模块设计用户端功能需包含注册登录、店铺浏览、预约下单、支付系统、评价反…...

计算机基础:从半导体到CPU指令执行全解析

1. 从半导体到逻辑门&#xff1a;计算机的物理基础 计算机的核心部件CPU本质上是由无数微小开关组成的精密电路&#xff0c;而这些开关的物理基础就是半导体材料。半导体之所以被称为"半导体"&#xff0c;是因为它的导电性介于导体和绝缘体之间。这种特性使得我们可以…...

PCB板验证

铺铜完成是PCB设计中的一个重要里程碑&#xff0c;但还不是终点。在发送给板厂生产之前&#xff0c;还需要完成一系列关键的验证、优化和文件输出工作。简单来说&#xff0c;铺铜之后的标准流程是&#xff1a;设计验证&#xff08;DRC/DFM&#xff09; → 必要分析&#xff08;…...

不用pip也能装!3种方法在Pycharm中配置wxPython(含离线安装技巧)

突破网络限制&#xff1a;PyCharm中wxPython的3种高阶安装方案 在企业开发环境中&#xff0c;网络访问限制常常成为Python包管理的"拦路虎"。特别是像wxPython这样包含二进制扩展的GUI库&#xff0c;传统pip安装方式在离线环境下几乎束手无策。本文将揭秘三种无需依赖…...

从零到一:基于LLaMA-Factory与Ollama的本地大模型定制化实战

1. 为什么需要本地定制化大模型&#xff1f; 最近两年&#xff0c;大语言模型的发展速度简直让人瞠目结舌。从最初的GPT-3到现在的Llama 3&#xff0c;模型能力越来越强&#xff0c;但随之而来的问题是&#xff1a;这些通用大模型真的能满足我们每个人的特定需求吗&#xff1f;…...

WPS加载项开发实战:从零到一构建你的第一个wpsjs插件

1. 为什么你需要WPS加载项开发 第一次听说WPS加载项时&#xff0c;我也是一头雾水。直到接手了一个客户需求——他们需要在WPS里快速生成固定格式的周报模板&#xff0c;我才真正体会到这个功能的价值。想象一下&#xff0c;你每天要处理几十份格式雷同的文档&#xff0c;如果能…...

避坑指南:Java下载MinIO目录时,路径处理、空文件夹和权限的那些坑

Java与MinIO目录下载实战&#xff1a;从路径陷阱到权限优化的深度解析 1. 当MinIO目录下载遇上真实开发场景 在云存储时代&#xff0c;MinIO作为高性能的对象存储解决方案&#xff0c;已经成为Java开发者处理文件存储的热门选择。但当我们从简单的单文件操作转向复杂的目录下载…...