python全栈学习记录(二十四)元类、异常处理
元类、异常处理
文章目录
- 元类、异常处理
- 一、元类
- 1.元类控制类的实例化
- 2.属性/方法的查找顺序
- 3.单例
- 二、异常处理
一、元类
1.元类控制类的实例化
类的__call__方法会在产生的对象被调用时自动触发,args和kwargs就是调用实例时传入的参数,返回值是调用实例以后的结果。
class A():def __call__(self, *args, **kwargs):print("from __call__")print(args,kwargs)return 333a=A()
print(a(111,k=222))<<<from __call__
<<<(111,) {'k': 222}
<<<333
一般情况下类的__call__函数会完成以下的几件事情:创建一个新对象、根据传入的值完成新对象的初始化、返回新建的对象。换句话说__new__和__init__两个方法是在__call__方法里面完成的。
基于此我们就可以通过复写元类的__call__方法完成对类实例化的控制效果。
class Mymeta(type):def __call__(self, *args, **kwargs):#因为是类调用的时候触发了__call__方法,所以此处的self是People# 1、先造出一个People的空对象#obj=object.__new__(self)obj=self.__new__(self)# 2、用People的初始化方法为新建的People对象完成初始化self.__init__(obj,*args,**kwargs)# 3、返回初始好的对象return objclass People(object,metaclass=Mymeta):country='China'def __init__(self,name,age):self.name=nameself.age=ageprint(People('111',222))<<< <__main__.People object at 0x0000022AFFB9AE80>
上述代码中当调用People(‘111’,222)时,触发元类的__call__方法,首先会调用People的__new__方法产生一个People类的新对象,由于People没有__new__方法,根据继承的机制解释器会去父类object中找,新对象产生后就需要根据People类的初始化方法完成对象的初始化,所以我们调用People的初始化方法并将新产生的obj对象传入完成初始化操作,最后返回这个obj对象也就完成了实例化的操作了。我们完全可以在__call__方法的内部添加一些功能已完成实例的定制,例如下面要讲到的单例。
2.属性/方法的查找顺序
python类的属性/方法的查找顺序为:
- 先在对象层查找,当前对象找不到就去找父类(mro表)
- 如果父类也找不到再去对象上一级查找(注意实例和类、类和元类都是跨一级的关系)
- 但是属性/方法的查找最多只能跨一级(例如实例中调用属性,在对应类及其父类中找不到就结束了,因为实例到元类跨了两个级别,实例中调的属性无法去元类中查找)
根据上面的规则简单来讲就是:
- 在实例中查找:实例——对应的类——对应类的父类
- 在类中查找:类——父类——元类——元类的父类
python中继承和实例的关系如下:
- type是所有类的元类、也是自己的元类
- object是所有类的父类
- int、str、list等是object的子类,是type的实例
- 1、‘1’、[1]等是int、str、list的实例
- class创建的类是type的实例,是object的子类
3.单例
单例模式:基于某种方法实例化多次得到实例是同一个。
当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存地址以减少占用的空间。
例如现在我需要传入一个ip地址,我们自动最常用的ip是127.0.0.1,如果需要传入的是127.0.0.1那么就直接调用单例,如果是其他ip就创建新实例。这个需求可以有三种方法实现:
方式一:内置属性法
class Single:__instacne=None#默认的ip值__ip="127.0.0.1"def __init__(self,ip):self.ip=ip#使用默认的ip单例@classmethoddef from_conf(cls):if cls.__instacne is None:cls.__instacne=cls(cls.__ip)return cls.__instacneobj1=Single('127.10.0.10')
obj2=Single.from_conf()
obj3=Single.from_conf()
print(obj1,obj2,obj3)
<<< <__main__.Single object at 0x0000021A1F24AEB0> <__main__.Single object at 0x0000021A1F24ADF0> <__main__.Single object at 0x0000021A1F24ADF0>
方法二:装饰器
def singleton(cls):#闭包函数内存一个传默认值的实例cls.__instance=cls('127.0.0.1')def wrapper(*args,**kwargs):#不传值则返回存的单例if len(args) == 0 and len(kwargs) == 0:return cls.__instancereturn cls(*args,**kwargs)return wrapper@singleton
class Single:def __init__(self,ip):self.ip=ipobj1=Single('127.10.0.10')
obj2=Single()
obj3=Single()
print(obj1,obj2,obj3)
<<< <__main__.Single object at 0x000001F5E256AD60> <__main__.Single object at 0x000001F5E256AE80> <__main__.Single object at 0x000001F5E256AE80>
方法三:元类控制单例的产生
class Mymeta(type):#初始化类的过程需要传入class_name,class_bases,class_dicdef __init__(self,class_name,class_bases,class_dic):#继承type的__init__方法初始化Singlesuper(Mymeta,self).__init__(class_name,class_bases,class_dic )#由于Single需要一个内置属性存放单例,所以在初始化类的过程中完成单例的创建self.__instance = self.__new__(self) # 造出一个Mysql的对象self.__init__(self.__instance, '127.0.0.1')def __call__(self, *args, **kwargs):#当实例化不传参时,返回单例,传参则正常完成实例化if len(args) == 0 and len(kwargs) == 0:return self.__instanceobj=self.__new__(self)self.__init__(obj,*args,**kwargs)return objclass Single(metaclass=Mymeta):def __init__(self,ip):self.ip=ipobj1=Single('127.10.0.10')
obj2=Single()
obj3=Single()
print(obj1,obj2,obj3)
<<< <__main__.Single object at 0x000001CA60BFCAF0> <__main__.Single object at 0x000001CA60BFCC40> <__main__.Single object at 0x000001CA60BFCC40>
二、异常处理
当程序运行过程中出现错误时,就会报错,这个就是异常。如果我们希望代码在可能发生错误的情况下依然能正常运行,就需要用到异常处理。但是需要注意异常处理并不是越多越好,如果程序中的错误是可以预知的,应该尽可能不使用异常处理,只有当程序中的错误是不可预知的,才需要使用到异常处理。
异常处理的常用格式:
#当try中的程序运行出现错误时会跳转到except处,根据except后的信息处理错误
#except ValueError表示出现ValueError错误时出现跳转到except处运行下面的代码,如果出现其他错误则直接报错
try:代码块
except ValueError:代码块
#同时接受多个错误
except (IOError,NameError):代码块
#接受错误并打印错误信息
except ImportError as e:#e为错误信息print(e)
#except Exception表示接受所有的错误,Exception可以不写
except Exception:代码块#else表示try中的代码没有异常时运行,finally表示try except代码运行完以后运行,通常用来回收资源
try:代码块
except:代码块
else:代码块
finally:代码块
常见的错误形式:
断言:
#assert会在不满足后面的条件时报错,一般用于测试阶段
l=[1,2]
assert len(l)==3
<<<AssertionError
raise:
#程序运行至raise处时会抛出后面的错误
raise ValueError('找不到值')
<<<ValueError: 找不到值
自定义异常:
#自定义的错误类必须继承BaseException类
class NagaException(BaseException):def __init__(self,data):self.data=datadef __str__(self):return self.datatry:raise NagaException('自定义错误')
except NagaException as e:print(e)
<<<自定义错误
相关文章:

python全栈学习记录(二十四)元类、异常处理
元类、异常处理 文章目录 元类、异常处理一、元类1.元类控制类的实例化2.属性/方法的查找顺序3.单例 二、异常处理 一、元类 1.元类控制类的实例化 类的__call__方法会在产生的对象被调用时自动触发,args和kwargs就是调用实例时传入的参数,返回值是调用…...
Golang Slice扩容机制及注意事项
Golang Slice扩容机制及注意事项: 在 Go语言中,Slice(切片)是一种非常灵活且强大的数据结构,它是对数组的抽象,提供了动态数组的功能。Slice 的扩容机制是自动的,但了解其背后的原理对于编写高…...

华为OD机试 - 猜数字 - 暴力枚举(Python/JS/C/C++ 2024 E卷 100分)
华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,…...
Flink触发器Trigger
前言 在 Flink 窗口计算模型中,数据先经过 WindowAssigner 分配窗口,然后再经过触发器 Trigger,Trigger 决定了一个窗口何时被 ProcessFunction 处理。每个 WindowAssigner 都有一个默认的 Trigger,如果默认的不满足需求…...
【操作系统的使用】Linux 系统环境变量与服务管理:设置与控制的艺术
文章目录 系统环境变量与服务管理:设置与控制的艺术一、系统环境变量的设置1.1 临时设置环境变量1.2 永久设置环境变量 二、服务启动类型的设置2.1 查看服务状态2.2 启动和停止服务2.3 设置服务的启动类型2.3.1 设置服务在启动时运行2.3.2 禁用服务在启动时运行2.3.…...
速盾:高防cdn配置中性能优化是什么?
高防CDN配置中的性能优化是指通过调整CDN配置以提升网站的加载速度、响应时间和用户体验。在进行性能优化时,需要考虑多个因素,包括CDN节点的选择和布置、缓存策略、缓存过期时间、预取和预加载、并发连接数和网络延迟等。 首先,CDN节点的选…...

Qt_软件添加版本信息
文章内容: 给生成的软件添加软件的版权等信息 #include <windows.h> //中文的话增加下面这一行 #pragma code_page(65001)VS_VERSION_INFO VERSIONINFO...
mallocfree和newdelete的区别
malloc\free和new\delete的区别 malloc/free new/delete 身份: 函数 运算符\关键字 返回值: void* 带类型的指针 参数: 字节个数(手动计算) 类型 自动计算字节数 处理数组: 手动计算数组总字节数 new 类型[数量] 扩容࿱…...

无锁队列实现(Michael Scott),伪代码与c++实现
一、Michael & Scoot 原版伪代码实现 structure pointer_t {ptr: pointer to node_t, count: unsigned integer}structure node_t {value: data type, next: pointer_t}structure queue_t {Head: pointer_t, Tail: pointer_t}initialize(Q: pointer to queue_t)node new_…...
猜数字小游戏
前言 猜数字游戏是一款经典且简单的互动游戏,常常用于提高逻辑思维能力和锻炼数学技巧。本文将深入探讨一段用 JavaScript 编写的猜数字游戏代码,帮助读者理解游戏的基本逻辑和实现方法。这段代码不仅适合初学者练习编程技巧,也是了解用户交…...

在Windows上搭建ChatTTS:从本地部署到远程AI音频生成全攻略
文章目录 前言1. 下载运行ChatTTS模型2. 安装Cpolar工具3. 实现公网访问4. 配置ChatTTS固定公网地址 前言 本篇文章主要介绍如何快速地在Windows系统电脑中本地部署ChatTTS开源文本转语音项目,并且我们还可以结合Cpolar内网穿透工具创建公网地址,随时随…...

如何用好 CloudFlare 的速率限制防御攻击
最近也不知道咋回事儿,群里好多站长都反映被CC 攻击了。有人说依旧是 PCDN 干的,但明月感觉不像,因为有几个站长被 CC 攻击都是各种动态请求(这里的动态请求指的是.php 文件的请求)。经常被攻击的站长们都知道,WordPress /Typecho 这类动态博客系统最怕的就是这种动态请求…...
Unity3D 立方体纹理与自制天空盒详解
立方体纹理和自制天空盒是游戏开发中常用的技术之一,可以为游戏增添更加丰富的视觉效果。在本文中,我们将详细介绍Unity3D中立方体纹理和自制天空盒的使用方法,并给出相应的代码实现。 对惹,这里有一个游戏开发交流小组ÿ…...
【工具】VSCODE下载,配置初次设置
打开 settings.json 文件,包含了 Visual Studio Code (VSCode) 中的各种用户配置。 {"files.associations": {"*.vue": "vue","*.wpy": "vue","*.wxml": "html","*.wxss": "…...

vue使用jquery的ajax,页面跳转
一、引入jquery依赖 打开终端更新npm npm install -g npm 更新完后引入输入npm install jquery 加载完后 在最外层的package.json文件中加入以下代码 配置好后导入jquery 设置变量用于接收服务器传输的数据 定义ajax申请数据 服务器的Controller层传输数据 (…...

基于微信小程序的社区二手交易系统的详细设计和实现(源码+lw+部署文档+讲解等)
项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…...

D34【python 接口自动化学习】- python基础之输入输出与文件操作
day34 文件关闭 学习日期:20241011 学习目标:输入输出与文件操作﹣-46 常见常新:文件的关闭 学习笔记: 文件关闭的内部工作过程 close()函数 with语句 常用的打开关闭文件 # 文件关闭 # 方式…...

【Linux系列】set -euo pipefail 命令详解
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

【Python爬虫实战】正则:中文匹配与贪婪非贪婪模式详解
🌈个人主页:https://blog.csdn.net/2401_86688088?typeblog 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、匹配中文 (一)匹配单个中文字符 (二…...
保护数据安全:JS前端加密与PHP后端解密实战教程,让敏感信息更安全
保护数据安全:JS前端加密与PHP后端解密实战教程,让敏感信息更安全 在Web开发中,确保用户提交的敏感信息(如密码、手机号码等)的安全性是非常重要的。一种常见的做法是使用加密技术来保护这些数据,在传输过…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...