动态属性@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

相关文章

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.使用场景详细对

Python如何调用另一个类的方法和属性

《Python如何调用另一个类的方法和属性》在Python面向对象编程中,类与类之间的交互是非常常见的场景,本文将详细介绍在Python中一个类如何调用另一个类的方法和属性,大家可以根据需要进行选择... 目录一、前言二、基本调用方式通过实例化调用通过类继承调用三、高级调用方式通过组合方式调用通过类方法/静

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到

spring中的@MapperScan注解属性解析

《spring中的@MapperScan注解属性解析》@MapperScan是Spring集成MyBatis时自动扫描Mapper接口的注解,简化配置并支持多数据源,通过属性控制扫描路径和过滤条件,利... 目录一、核心功能与作用二、注解属性解析三、底层实现原理四、使用场景与最佳实践五、注意事项与常见问题六

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注