Python类的自定义属性访问及动态属性设置
本文主要介绍python类的一些自定义属性访问的方法,以及类的动态属性设置即python的内置函数setattr()。
自定义属性访问
什么是属性?下面的例子a和b是属性吗?不是,他们是全局变量,属性(attribute)是类中的成员变量,也可以理解为属性就是类变量。
a = 11234
b = 'python'
类中的变量是静态变量,类可以直接访问,python是一门动态语言,任何实例对象都可以动态地添加或删除属性,一个类定义了一个作用域,类实例对象也引入了一个作用域,这与类定义的作用域是不同的。在类实例对象中查找属性的时候,首先在实例自己的作用域中查找,如果没有找到,则再去类定义的作用域中查找。
在对类实例属性进行赋值的时候,实际上会在类实例定义的作用域中添加一个属性或修改一个属性,但并不会影响到对应类中定义的同名属性。那么从访问属性到返回结果的过程是怎么运作的呢?是通过下面几个魔术方法来实现的。
相关方法的使用
__getattribute__
:查找属性时会先触发该方法进行属性查找__getattr__
:查找属性没找到的时候触发__setattr__
:设置属性的时候触发__delattr__
:删除属性的时候触发
为了直观地感受实例访问属性时都做了什么,我们看一下下面的例子:
class TestCase:att_1 = 'hello' # 定义类属性att_2 = 'python'def test_func(self): # 定义方法print("这是一个方法")def __getattribute__(self, item):# 属性访问拦截器:当对象访问属性时,会自动触发这个方法,由这个方法来决定返回的属性值# 应用场景:访问不存在的属性时,不希望它报错,可以用try--except来捕获异常返回一个值或提示信息# try:# return super().__getattribute__(item) # 调用父类真正的__getattribute__方法返回正确的属性值# except AttributeError:# print(item,':该属性不存在!')# 如果使用了try方法就不会触发__getattr__方法了,因为找不到属性时的异常已经在这里被捕获了print("我是__getattribute__,我正在工作")return super().__getattribute__(item) # 调用父类的方法,返回找到的结果,不调用就不会返回def __getattr__(self, att_name):# 当对象访问属性时,属性不存在,引发异常,会被__getattr__方法捕获# 然后执行该方法的代码,相当于自带捕获异常print("我是__getattr__,我正在工作")return att_name + "这是我要找的东西,但是我找不到"def __setattr__(self, att_name, value):# 设置属性的时候就会触发该方法print("我是__setattr__,我正在工作")super().__setattr__(att_name, value) # 调用父类的方法,设置属性,不调用就不会真的设置属性def __delattr__(self, att_name):print("我是__delattr__,我正在工作")print("这是我即将删除的东西{}".format(att_name))super().__delattr__(att_name) # 调用父类的方法,删除属性,不调用就删除不了res = TestCase() # 实例化对象
print('-----------------访问属性----------------')
print(res.att_1) # 访问类属性,通过运行结果看res实例对象访问属性时通过了方法__getattribute__print('\n-----------------访问不存在的属性----------------')
print(res.att_3)print('\n-----------------设置属性----------------')
res.att_3 = 'new_attr'print('\n-----------------删除属性----------------')
del res.att_3
运行结果:
-----------------访问属性----------------
我是__getattribute__,我正在工作
hello-----------------访问不存在的属性----------------
我是__getattribute__,我正在工作
我是__getattr__,我正在工作
att_3这是我要找的东西,但是我找不到-----------------设置属性----------------
我是__setattr__,我正在工作-----------------删除属性----------------
我是__delattr__,我正在工作
这是我即将删除的东西att_3
从结果中,我们可以看到当实例访问属性时,就会自动触发__getattribute__()
方法,然后由这个方法来决定返回的属性值;当实例访问不存在的属性时,会引发异常,而这个异常会被__getattr__()
方法捕获,然后执行该方法的代码,相当于自带捕获异常;同理,在设置属性或删除属性时,会自动触发对应的__setattr__()
方法或__delattr__()
方法。
但需要注意的是,在自定义这些方法的时候,一定要记得调用对应的父类方法,将结果返回,否则只是执行了你自定义的东西并没有真正去做它本身要去做的事情。
动态属性设置
setattr()是python的一个内置函数,用于动态设置实例属性,语法:setattr(object, name, value)
参数1:object-对象
参数2:name-给对象要设置的属性名(字符串类型)
参数3:value-属性值
'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:725638078
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class TestCase:"""这是一个存放测试用例数据的类"""passcases = [{'case_id': 1, 'data': '123', 'actual': '不通过', 'excepted': '通过'},{'case_id': 2, 'data': '123', 'actual': '通过', 'excepted': '通过'},{'case_id': 3, 'data': '123', 'actual': '不通过', 'excepted': '通过'},{'case_id': 4, 'data': '123', 'actual': '通过', 'excepted': '通过'},
]res = [] # 新建空列表用于存放结果
for i in cases:case = TestCase() # 创建一个实例对象for k, v in i.items():# 把毎条用例数据中字典的key和value设成该实例的属性与值,比如:case_id = 1,data = 123等,把一个字典的全部键值对设为一个实例的属性setattr(case, k, v) res.append(case) # 把创建的对象存到结果中print(res) # 存放的是对象,共4个
print("\n按字段读取第一条测试用例数据:")
print("case_id:", res[0].case_id) # 读取第一个对象的case_id属性值
print("data:", res[0].data)
print("actual:", res[0].actual)
print("excepted:", res[0].excepted)print("\n读取完整的第一条测试用例数据:")
print(res[0].__dict__)
运行结果:
[<__main__.TestCase object at 0x0000019F15F573C8>, <__main__.TestCase object at 0x0000019F15F57C18>, <__main__.TestCase object at 0x0000019F16009C18>, <__main__.TestCase object at 0x0000019F16009C50>]按字段读取第一条测试用例数据:
case_id: 1
data: 123
actual: 不通过
excepted: 通过读取完整的第一条测试用例数据:
{'case_id': 1, 'data': '123', 'actual': '不通过', 'excepted': '通过'}
上面的运行结果中,像<main.TestCase object at 0x0000019F15F573C8>这就是一个TestCase()类的实例对象,这是它的内存地址,setattr()动态设置属性,就相当于case.case_id=1给实例设置一个属性,只是上面所举例是循环地把整个列表的数据拆分成4个实例的属性。
同样的,python中对应还有一个getattr(object, name)内置函数,它是用于返回一个实例的属性,需要两个参数,一个是对象名,一个是属性名,返回该属性的属性值,这里不再举例,自己使用一下吧!
另外,上述例子中最后还用到了一个__dict__
对象属性,它是用于获取实例对象的所有属性,并以字典的形式返回。
结尾给大家推荐一个非常好的学习教程,希望对你学习Python有帮助!
Python基础入门教程推荐:更多Python视频教程-关注B站:Python学习者
Python爬虫案例教程推荐:更多Python视频教程-关注B站:Python学习者
Python类的自定义属性访问及动态属性设置相关推荐
- 怎么用python画心_python怎么画心Python的类实例属性访问规则
一般来说,在Python中,类实例属性的访问规则算是比较直观的. 但是,仍然存在一些不是很直观的地方,特别是对C++和Java程序员来说,更是如此. 在这里,我们需要明白以下几个地方: 1.Pytho ...
- python模型的属性是什么_Python的自定义属性访问跟描述器以及ORM模型的简单介绍...
一 . 自定义属性访问 1.__getattr__ 作用:当我们访问属性的时候,如果属性不存在(出现AttrError),该方法会被触发. 2.__getattribute__ 作用:访问属性的时候, ...
- Python类属性访问的魔法方法
Python类属性访问的魔法方法: 1. __getattr__(self, name) - 定义当用户试图获取一个不存在的属性时的行为 2. __getattribute__(self, name) ...
- python类中包含一个特殊的变量、它可以访问类的成员_Python 类的特殊成员介绍...
类的成员有两种形式 公有成员,在任何地方都能访问 私有成员,只有在类的内部才能方法,私有成员命名时,前两个字符是下划线. class Foo: def __init__(self, name, age ...
- python 类和对象_面向对象的编程思想和Python的类,访问和属性,继承
面向对象的编程思想和Python的类,类的方法和属性,实例方法这一文从面向对象的角度,介绍类的定义,类的属性和自定义方法. 本文将从访问限制,属性,继承,方法重写这几个方面继续介绍面向对象的编程思想和 ...
- python定义私有变量的方法_Python怎么修改私有属性 如何访问python类中的私有方法...
python 类为什么不能定义私有属性和方法 因为b.name[0] = 'zhang'修改的是类属性,类属性是全局的,所有的实例共享,如果想私有化,可以添加 def __init__( self ) ...
- python 类中定义列表_Python-从类定义中的列表理解访问类变量
小编典典 类范围和列表,集合或字典的理解以及生成器表达式不混合. 为什么:或者,官方用词 在Python 3中,为列表理解赋予了它们自己的适当范围(本地名称空间),以防止其局部变量渗入周围的范围内(即 ...
- python类中包含一个特殊的变量、它可以访问类的成员_区域联防的运用中遵循并贯彻以球为主的防守原则,做到球人区三者兼顾。( )...
刘墉书法的特点是用墨厚重,体丰骨劲,浑厚敦实,别具面目.A:对B:错 Python类中包含一个特殊的变量(),它表示当前对象自身,可以访问类的成员.A:meB:selfC:thisD:与类同名 在过火 ...
- python类中包含一个特殊的变量、它可以访问类的成员_Python类中包含一个特殊的变量( ),它表示当前对象自身,可以访问类的成员....
包含票务系统的业务管理主要内容包括()A:运营监督B:规则管理C:信息管理D:财务管理E:模式管理 特殊表嘌呤核苷酸补救合成途径的主要器官是().A:脑组织B:小肠C:胸腺D:肝脏E:肾脏 示当身嘌呤 ...
最新文章
- OkHttp源码分析
- oftp-2协议服务器,科普:Oasis自研通信协议与互联网分层架构
- DataReader 要在事务提交前 CLOSE 掉 否则会报一个:已有打开的与此命令相关联的 DataReader,必须首先将它关闭。...
- 在java 里kv 是什么_consul kv使用介绍
- BZOJ 2243 染色(树链剖分好题)
- Python面试笔记二
- 软考路:高项4流水账
- 关于微信小程序中uView中通过packer选择器修改表单无法触发form组件的表单验证的问题
- python课程第三周小结_python周报第三周
- 移远 EC20 模组(4G通信模组)转载
- 趋势防毒墙网络版的安装部署(officescan)
- 电脑主机插入耳机无声音
- Flash反编译软件ASV2013之SWF转Fla教程
- window计算机桌面的组成,Windows 10桌面的组成,Win10桌面介绍
- 一个简单的网页制作作业,宠物html静态网页制作成品代码(学生网页设计作业源码)
- 经典电影list(辛辛苦苦整理的)
- cmd 删除系统垃圾文件
- 店盈通:拼多多推广技巧步骤
- 使用Nginx中遇到的一个小问题思考
- 高等数学——常用结论(3)