[Python进阶]定制类:属性篇

4.10.2 属性篇

4.10.2.1 getattrgetattribute

通常我们可以通过obj.attr访问某个对象的属性。而__getattr__则是用来处理我们在获取某个不存在的属性时希望的处理。
默认情况下,如果我们获取了一个不存在的属性时,会报错:AttributeError。

from icecream import icclass A:def __init__(self):self.test = 't'def __getattr__(self, item):print(f'getting {item}')raise AttributeErrora = A()
ic(a.test)

ic| a.test: ‘t’

如果存在属性,则不会调用__getattr__方法。否则将会调用该方法:

from icecream import icclass A:def __init__(self):...def __getattr__(self, item):print(f'getting {item}')raise AttributeErrora = A()
ic(a.test)

Traceback (most recent call last):
File “E:\BaiduSyncdisk\FrbPythonFiles\t1.py”, line 14, in
ic(a.test)
File “E:\BaiduSyncdisk\FrbPythonFiles\t1.py”, line 10, in getattr
raise AttributeError
AttributeError
getting test

__getattribute__方法则是只要尝试获取某个属性,不管这个属性存在不存在,都会调用该方法。

from icecream import icclass A:def __init__(self):self.data = 'abc'self.counter = 0def __getattribute__(self, name):if name == 'data':self.counter += 1return super().__getattribute__(name)o = A()
ic(o.data)
ic(o.data)
ic(o.counter)

ic| o.data: ‘abc’
ic| o.data: ‘abc’
ic| o.counter: 2

注意:
1、在重写__getattr__和__getattribute__方法时,很容易造成无限递归的情况,因为,只要在这2个方法中引用了属性,那么又会很容易再次调用这2个方法。
2、当存在着2个方法时,调用了某个不存在的属性时,只会调用__getattribute__方法,而不会调用__getattr__方法。

4.10.2.2 setattr

在类属性赋值的时候会调用魔法方法__setattr__,即便是在类的初始化__init__方法中也一样。我们可以通过super().setattr(name, value)调用类的默认属性赋值方法。

from icecream import icclass A:def __init__(self):self.data = 'abc'self.counter = 0def __setattr__(self, name, value):print('setattr', name, value)super().__setattr__(name, value)o = A()
ic(o.data)
o.data = 'ufo'

setattr data abc
setattr counter 0
setattr data ufo
14:16:43|> o.data: ‘abc’

4.10.2.3 delattr

当我们尝试用del关键字删除对象中某个属性时,就会调用__delattr__魔法方法。

from icecream import icclass A:def __init__(self):self.data = 'abc'self.counter = 0def __delattr__(self, name):print('delattr', name)super().__delattr__(name)o = A()
del o.data
ic(o.data)

delattr data
Traceback (most recent call last):
File “E:\t1.py”, line 16, in
ic(o.data)
AttributeError: ‘A’ object has no attribute ‘data’

4.10.2.4 dir

通常我们可以通过使用dir函数获取到某个对象的内置属性和方法等信息。可以通过修改对象中的__dir__魔法方法进行定制化返回结果。

from icecream import icclass A:def __init__(self):self.data = 'abc'def test(self):...def __dir__(self):return [None]o = A()
ic(dir(o))

14:28:15|> dir(o): [None]

4.10.2.5 getsetdelete

在Python中,魔法方法__get__用于定义一个描述符(descriptor)。描述符是一种带有"绑定行为"的对象,其主要目的是管理类和实例成员的访问。在访问对象的属性时,当Python检测到它属于描述符时,就会自动调用相应的描述符方法。
下面是一个简单的例子,演示了如何使用__get__魔法方法来创建一个简单的计数器描述符:

class Counter:def __init__(self):self.value = 0def __get__(self, instance, owner):return self.valuedef __set__(self, instance, value):self.value = value if value > 0 else 0def __delete__(self, instance):print(instance, 'del')class MyClass:counter = Counter()obj = MyClass()
print(obj.counter) # 输出 0
obj.counter = -1
print(obj.counter) # 输出 0
obj.counter = 10
print(obj.counter) # 输出 10
del obj.counter

<main.MyClass object at 0x000002AEF8BEBDC0> del

在上面的代码中,我们使用Counter类创建了一个计数器描述符,并将其作为MyClass类的成员变量counter进行使用。当我们尝试读取MyClass实例的counter属性时,Python会自动调用Counter类中的__get__方法来返回该计数器的值。当我们尝试设置counter属性时,Python会自动调用Counter类中的__set__方法来设置计数器的值。
这个描述符确保计数器不会被负数重置,并且永远只会递增。实际上,我们的代码中没有对计数器递增做任何操作,但是当你在实际应用场景中使用描述符时,可能会在__get__和__set__方法中添加更多的逻辑。例如,你可以创建一个验证器描述符,它将确保属性值满足某些条件。
当删除该描述器时会调用__delete__方法。

4.10.2.6 slots(类属性)

在Python中,__slots__是一个类属性(class attribute),用于限制实例能够动态绑定的属性。它是一个字符串或字符串组成的元组,其中包含类允许的属性名称列表。
使用__slots__可以有效地减少实例所占用的内存空间,并提高访问实例属性的速度。这是因为它将属性名存储在特殊数组 slots 中,而不是在每个实例中创建一个字典来存储属性。
下面是一个简单的例子,演示了如何在类中使用__slots__属性:

class Person:__slots__ = ('name', 'age')def __init__(self, name, age):self.name = nameself.age = agep = Person('John', 30)
print(p.name)  # output: John
print(p.age)   # output: 30p.email = 'john@example.com'  # AttributeError: 'Person' object has no attribute 'email'

在这个例子中,我们定义了一个Person类,并将它的__slots__设置为(‘name’, ‘age’)。这意味着Person类只允许动态绑定name和age属性,任何其他属性都会抛出AttributeError异常。通过这种方式,我们可以确保Person类中只维护预定义的属性。

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

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

相关文章

如何做好Code Review:思考、方法和实践 (真实经验总结)

目录 背景 Code Review 目标 系统层面 代码规范 业务逻辑 日志 测试 安全

k8s1.26.6 安装gitlab

Gitlab官方提供了 Helm 的方式在 Kubernetes 集群中来快速安装&#xff0c;但是在使用的过程中发现 Helm 提供的 Chart 包中有很多其他额外的配置&#xff0c;所以我们这里使用自定义的方式来安装&#xff0c;也就是自己来定义一些资源清单文件。 Gitlab主要涉及到3个应用&…

Python爬虫时遇到连接超时解决方案

在进行Python爬虫任务时&#xff0c;经常会遇到连接超时&#xff08;TimeoutError&#xff09;错误。连接超时意味着爬虫无法在规定的时间内建立与目标服务器的连接&#xff0c;导致请求失败。为了帮助您解决这个常见的问题&#xff0c;本文将提供一些解决办法&#xff0c;并提…

用合成数据训练托盘检测模型【机器学习】

想象一下&#xff0c;你是一名机器人或机器学习 (ML) 工程师&#xff0c;负责开发一个模型来检测托盘&#xff0c;以便叉车可以操纵它们。 ‌你熟悉传统的深度学习流程&#xff0c;已经整理了手动标注的数据集&#xff0c;并且已经训练了成功的模型。 推荐&#xff1a;用 NSDT设…

【LeetCode】88. 合并两个有序数组

这道题我总共想了三种解法。 1.将nums2中的元素依次放入nums1有效元素的后面&#xff0c;再总体进行排序。 import java.util.*; class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {int j 0;for(int i m;i<mn;i){nums1[i] nums2[j];j;}Arrays…

搭建网站 --- 快速WordPress个人博客并内网穿透发布到互联网

文章目录 快速WordPress个人博客并内网穿透发布到互联网 快速WordPress个人博客并内网穿透发布到互联网 我们能够通过cpolar完整的搭建起一个属于自己的网站&#xff0c;并且通过cpolar建立的数据隧道&#xff0c;从而让我们存放在本地电脑上的网站&#xff0c;能够为公众互联…

机器学习分布式框架ray运行xgboost实例

Ray是一个开源的分布式计算框架&#xff0c;专门用于构建高性能的机器学习和深度学习应用程序。它的目标是简化分布式计算的复杂性&#xff0c;使得用户能够轻松地将任务并行化并在多台机器上运行&#xff0c;以加速训练和推理的速度。Ray的主要特点包括支持分布式任务执行、Ac…

vue3单选选择全部传all,否则可以多选

<el-form-item label"发布范围-单位选择"><el-radio-group v-model"formData.unitRadio" change"getUnit"><el-radio label"ALL" click.prevent"radioChange(ALL)">全部</el-radio><el-radio la…

限流简单实例

1、限流算法 &#xff08;1&#xff09;固定窗口计数器算法 固定窗口其实就是时间窗口。固定窗口计数器算法规定了我们单位时间处理的请求数量。 思路如下&#xff1a; 1&#xff09;给定一个变量counter来记录当前接口处理的请求数量&#xff0c;初始值为0&#xff08;代表接口…

微信开发者工具 miniprogram_npm 未找到

背景 微信开发者工具中&#xff0c;打开集成了vant-weapp的项目&#xff0c;构建npm时&#xff0c;报错\miniprogram_npm\ 未找到。 问题 微信开发者工具&#xff0c;工具----->构建npm时&#xff0c;提示 message&#xff1a;发生错误 Error: D:\some\path\miniprogram…

Linux 命令学习:

1. PS命令 ps 的aux和-ef区别 1、输出风格不同&#xff0c;展示的格式略有不同 两者的输出结果差别不大&#xff0c;但展示风格不同。aux是BSD风格&#xff0c;-ef是System V风格。 2、aux会截断command列&#xff0c;而-ef不会&#xff0c;当结合grep时这种区别会影响到结果 …

java 企业工程管理系统软件源码+Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis em

&#xfeff; 工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据…

【C++】STL——list的模拟实现、构造函数、迭代器类的实现、运算符重载、增删查改

文章目录 1.模拟实现list1.1构造函数1.2迭代器类的实现1.3运算符重载1.4增删查改 1.模拟实现list list使用文章 1.1构造函数 析构函数 在定义了一个类模板list时。我们让该类模板包含了一个内部结构体_list_node&#xff0c;用于表示链表的节点。该结构体包含了指向前一个节点…

深度学习入门 ---- 张量(Tensor)

文章目录 张量张量在深度学习领域的定义张量的基本属性使用PyTorch安装PyTorch查看安装版本 创建张量常用函数四种创建张量的方式和区别 四则运算 张量 张量在深度学习领域的定义 张量&#xff08;tensor&#xff09;是多维数组&#xff0c;目的是把向量、矩阵推向更高的维度。…

uniapp 微信小程序:v-model双向绑定问题(自定义 props 名无效)

uniapp 微信小程序&#xff1a;v-model双向绑定问题&#xff08;自定义 props 名无效&#xff09; 前言问题双向绑定示例使用 v-model使用 v-bind v-on使用 sync 修饰符 参考资料 前言 VUE中父子组件传递数据的基本套路&#xff1a; 父传子 props子传父 this.$emit(事件名, …

如何安装、部署、启动Jenkins

一、测试环境 Linux系统 Centos 7 二、安装步骤&#xff1a; 1、安装jdk 我安装的是jdk8&#xff0c;此处就不多说了&#xff0c;自己百度哈&#xff0c;很简单 2、安装jenkins 首先依次执行如下三个命令&#xff1a; 2.1、导入镜像&#xff1a; [rootcentos7 ~]# sudo …

华为OD机考真题--单词接龙--带答案

2023华为OD统一考试&#xff08;AB卷&#xff09;题库清单-带答案&#xff08;持续更新&#xff09;or2023年华为OD真题机考题库大全-带答案&#xff08;持续更新&#xff09; 题目描述&#xff1a; 单词接龙的规则是&#xff1a; 用于接龙的单词首字母必须要前一个单词的尾字母…

Python(五十八)什么是字典

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

tcpdump网络抓包工具的使用

tcpdump 是一款用在linux系统上的网络抓包工具 1、 基本语法 tcpdump 的常用参数如下&#xff1a; tcpdump -i eth0 -nn -s0 -v port 80-i : 选择要捕获的接口&#xff0c;通常是以太网卡或无线网卡&#xff0c;也可以是 vlan 或其他特殊接口。如果该系统上只有一个网络接口&…

学习C#编写上位机的基础知识和入门步骤:

00001. 掌握C#编程语言基础和.NET框架的使用。 00002. 学习WinForm窗体应用程序开发技术&#xff0c;包括控件的使用和事件驱动编程。 00003. 熟悉基本的数据结构和算法知识&#xff0c;如链表、栈、队列等。 00004. 理解串口通信协议和通信方法&#xff0c;用于与底层硬件设…