动态属性@property 、__getattr__和__getattribute__ 、 __new__ 和 __init__、属性描述符

2024-02-21 11:38

本文主要是介绍动态属性@property 、__getattr__和__getattribute__ 、 __new__ 和 __init__、属性描述符,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

动态属性 @property

from datetime import date, datetime
class User:def __init__(self, name, birthday):self.name = nameself.birthday = birthdayself._age = 0 # _代表这个属性不想暴露,代码上的规范。双下滑线隐藏。@property # 将age方法变为属性 、这个可以理解为get属性def age(self):# 获取他的年龄 当年年份-生日return datetime.now().year - self.birthday.year@age.setter # user.age=30 会运行这段代码def age(self, value):self._age = valueif __name__ == "__main__":user = User("bobby", date(year=1987, month=1, day=1))user.age = 30print (user._age)print(user.age)

__getattr__ ,__getattribute__

"""
__getattr__ 在查找不到属性的时候调用"""from datetime import date, datetime
class User:def __init__(self, name, birthday):self.name = nameself.birthday = birthdaydef __getattr__(self, item):# 查找不到属性的时候,进入到这里,返回# 可以查找到,不会进入到这里面# 可以写一些逻辑,比如不区分大小写return "no attr"if __name__ == "__main__":user = User("bobby", date(year=1987, month=1, day=1))print (user.age)"""
除了以上,还可以 如果类里面有 属性a = dict
我们想通过 A类 访问a(dict)里的属性 ,a = {"name"}  A.name
def __getattr__(self, item):return self.a[tiem]
"""# __getattribute__(self,item):
# 这个是访问任何属性,都会无条件进入这个。
# 这个能不重写,尽量不要碰。
# 不过写框架的时候,可能会用到。

属性描述符和属性的查找过程

"""
IntField 是专门判断是否为整数的类实现get set delte任何一个魔法函数,IntField 就变为属性描述符
"""
import numbersclass IntField:"""数据描述符"""def __get__(self,instance,owner):return self.valuedef __set__(self,instance,value):# 判断是否为Int类型if not isinstance(value,numbers.Integral):raise ValueError("int value need ")if value<0:raise ValueError("positive value need ")self.value = valuepassdef __delete__(self,instance):passclass NoneDataIntField:"""非数据属性描述符"""def __get__(self,instance,owner):return self.value class User:age = IntField()if __name__ == "__main__":user = User()user.age=30 # 赋值的时候,其实会调用User的set方法。print(user.age)
"""
属性描述符查找的完整过程
如果user是某个类的实例,那么user.age(以及等价的getattr(user,’age’)) getattr全局
首先调用__getattribute__。如果类定义了__getattr__方法
那么在__getattribute__抛出 AttributeError 的时候就会调用到__getattr__,
而对于描述符(__get__)的调用,则是发生在__getattribute__内部的。
user = User(), 那么user.age 顺序如下:(1)如果“age”是出现在User或其基类的__dict__中, 且age是data descriptor, 那么调用其__get__方法, 否则(2)如果“age”出现在user的__dict__中, 那么直接返回 obj.__dict__[‘age’], 否则(3)如果“age”出现在User或其基类的__dict__中(3.1)如果age是non-data descriptor,那么调用其__get__方法, 否则(3.2)返回 __dict__[‘age’](4)如果User有__getattr__方法,调用__getattr__方法,否则(5)抛出AttributeError"""

__new__ 和 __init__

class User:def __new__(cls,*args,**kwargs):print("in new")# 如果不返回,不会运行init,就没有name属性了return super().__new__(cls)def __init__(self,name):print("in init")self.name = name
if __name__ == "__main__":user = User("name")print(user.name)
"""
new用来控制对象的生成过程,在对象生成之前
init是用来完善对象的
如果new 不返回对象,则不会调用init方法
"""

这篇关于动态属性@property 、__getattr__和__getattribute__ 、 __new__ 和 __init__、属性描述符的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/731656

相关文章

C#借助Spire.XLS for .NET实现在Excel中添加文档属性

《C#借助Spire.XLSfor.NET实现在Excel中添加文档属性》在日常的数据处理和项目管理中,Excel文档扮演着举足轻重的角色,本文将深入探讨如何在C#中借助强大的第三方库Spire.... 目录为什么需要程序化添加Excel文档属性使用Spire.XLS for .NET库实现文档属性管理Sp

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

MyBatis-Plus使用动态表名分表查询的实现

《MyBatis-Plus使用动态表名分表查询的实现》本文主要介绍了MyBatis-Plus使用动态表名分表查询,主要是动态修改表名的几种常见场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录1. 引入依赖2. myBATis-plus配置3. TenantContext 类:租户上下文

Java中的随机数生成案例从范围字符串到动态区间应用

《Java中的随机数生成案例从范围字符串到动态区间应用》本文介绍了在Java中生成随机数的多种方法,并通过两个案例解析如何根据业务需求生成特定范围的随机数,本文通过两个实际案例详细介绍如何在java中... 目录Java中的随机数生成:从范围字符串到动态区间应用引言目录1. Java中的随机数生成基础基本随

基于Nacos实现SpringBoot动态定时任务调度

《基于Nacos实现SpringBoot动态定时任务调度》本文主要介绍了在SpringBoot项目中使用SpringScheduling实现定时任务,并通过Nacos动态配置Cron表达式实现任务的动... 目录背景实现动态变更定时机制配置化 cron 表达式Spring schedule 调度规则追踪定时

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S

vue监听属性watch的用法及使用场景详解

《vue监听属性watch的用法及使用场景详解》watch是vue中常用的监听器,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作,:本文主要介绍vue监听属性watch的用法及使用场景... 目录1. 监听属性 watch2. 常规用法3. 监听对象和route变化4. 使用场景附Watch 的

Python动态处理文件编码的完整指南

《Python动态处理文件编码的完整指南》在Python文件处理的高级应用中,我们经常会遇到需要动态处理文件编码的场景,本文将深入探讨Python中动态处理文件编码的技术,有需要的小伙伴可以了解下... 目录引言一、理解python的文件编码体系1.1 Python的IO层次结构1.2 编码问题的常见场景二

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

Go之errors.New和fmt.Errorf 的区别小结

《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考... 目录error的基本用法1. 获取错误信息2. 在条件判断中使用基本区别1.函数签名2.使用场景详细对