python对象方法 反射

 前言

类实例化得到的对象可以直接调用类中定义的函数,并且可以将对象本身作为第一个参数,那么类能不能也能像对象一样使用类体中的函数而不需要传递第一个参数呢?如果我们使用别人封装好的类,如何判断这个类或者对象是否有某个属性呢?本文就带小伙伴们一探究竟吧!

绑定方法与非绑定方法

首先需要明确的是在类中定义的函数称为方法,它和普通的函数有些不同,类中定义的函数分为两大类,分别是绑定方法和非绑定方法。

绑定方法

绑定方法的特殊之处在于将调用者本身当作第一个参数自动传入,绑定方法分为绑定给类的方法和绑定给类实例化的对象的方法,绑定给对象的方法调用者是对象,自动传入的参数就是对象;绑定给类的方法,调用者是类,自动传入的是类。

在类中正常定义的函数默认是绑定给对象的,而在类内定义的函数上加上装饰器@classmethod,该函数就被绑定给了类。

类方法在被类调用的时候,会自动将类作为第一个参数传递给该类方法,类方法通常用于在__init__的基础上提供额外的初始化实例的方式。需要注意的是,类方法就是专门给类用的,类实例化的对象调用类方法是没有意义的。

class Animal():
    
    def __init__(self, color):
        self.color = color
    
    @classmethod
    def create_new_animal(cls): 
        print('创建一个新的动物种类')
        
>>> Animal.create_new_animal
<bound method Animal.create_new_animal of <class '__main__.Animal'>>

>>> Animal.create_new_animal()  # 类调用类方法会将类本身当做第一个参数传给类方法
创建一个新的动物种类

非绑定方法

为类体中定义的函数加上@staticmethod后,该方法就会变成非绑定方法,也称为静态方法,被该装饰器装饰的函数会变成普通函数,不会绑定给任何对象,也没有了自动传参的效果。

class Animal():
    
    def __init__(self, color):
        self.color = color
    
    @staticmethod
    def create_new_animal():   # 静态方法没有自动传参的效果,就是普通的函数
        print('创建一个新的动物种类')
        
>>> Animal.create_new_animal
<function Animal.create_new_animal at 0x000001DAE53CE670>

>>> Animal.create_new_animal()
创建一个新的动物种类

>>> Animal('white').create_new_animal()
创建一个新的动物种类

反射

反射是指在程序运行过程中可以动态获取对象的属性信息,在程序运行过程中,如果要获取一个不知道有什么属性的对象,可以使用反射来分析出对象的属性。可能有小伙伴说了,可以使用对象.__dict__查看对象的属性呀,确实可以,但是在程序开发中不建议直接操作对象的这种以__开头的内置方法。

在Python中实现反射非常简单,如果想要获取一个不知道存有何种属性的对象的属性,可以通过内置Python解释器内置函数dir获取任意对象的属性列表,列表中的元素是字符串格式。

>>> class Test():
...     test = 'test'
...     def foo(self):
...         print('test foo')
...

>>> dir(Test)
[..., 'foo', 'test']

>>> dir(Test())
[..., 'foo', 'test']

获取了对象的属性列表,需要借助Python解释器内置函数hasattr setattr getattr delattr来操作对象的属性。

t = Test()

# hasattr(obj, '属性名'):判断对象是否有某个属性
>>> hasattr(t, 'test')
True
>>> hasattr(t, 'test1')
False

# setattr(obj, '属性名', '新的属性值'): 修改对象的某个值,如果属性名不存在则为对象添加属性
>>> setattr(t, 'test', 'test1')
>>> setattr(t, 'test1', 'test1')
>>> t.test
'test1'
>>> t.test1
'test1'

# getattr(obj, '属性名')  # 获取对象的属性值
>>> getattr(t, 'foo')
<bound method Test.foo of <__main__.Test object at 0x000001DAE4F9BF40>>
>>> getattr(t, 'test')
'test1'
>>> getattr(t, 'test1')
'test1'

# delattr(obj, '属性名')  # 删除对象的属性
>>> delattr(t, 'test1')
>>> hasattr(t, 'test1')
False

基于反射可以通过字符串十分灵活的操作对象的属性,反射的原理其实就是基于对象.__dict__实现的。

# 1 先通过调用dir功能,查看某一个对象下可以  .  出哪些属性
print(dir(obj))
# 2 通过字符串反射到真正的属性,得到属性值
print(obj.__dict__[dir(obj)[-2]])

内置方法

Python的Class机制内置了很多特殊的方法来帮助使用者高度定制自己的类,这些内置方法都是以双下划线开头和结尾的,会在满足某种条件时自动触发,我们以常用的__str____del__为例来简单介绍它们的使用。

__str__在打印对象的时候会自动触发,然后将返回值(必须是字符串类型)当作本次打印的结果输出,在自定义类中不存在__str__时,打印对象输出结果是对象的内存地址;在自定义类中存在__str__时,打印对象输出结果是__str__方法的返回值。

# 类中没有__str__方法
class Test:

    def test(self):
        print('test')


t = Test()
print(t)  # <__main__.Test object at 0x000001F9EE618FD0>


# 类中有__str__
class Test:

    def test(self):
        print('test')

    def __str__(self):
        return 'Test对象'
    
t = Test()
print(t)  # Test对象

__del__方法是在对象被删除时自动触发,由于python的垃圾回收机制会自动清理程序中没用的资源,因此如果一个对象只是占用应用程序的资源,没有必要定义__del__方法,但是如果设计到占用系统资源的话比如打开的文件对象,由于关系到操作系统的资源,python的垃圾回收机制派不上用场的时候,就需要为对象创建__del__方法,用于对象被删除后自动触发回收操作系统资源。

class Test:
    def __init__(self):
        self.x = open('a.txt',mode='w')
        # self.x = 占用的是操作系统资源

    def __del__(self):
        print('run')
        # 发起系统调用,告诉操作系统回收相关的系统资源
        self.x.close()

obj = T()
del obj # obj.__del__()

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

未来 AI 可能给哪些产业带来哪些进步与帮助?

AI时代如何要让公司在创新领域领先吗&#xff1f;拥抱这5种创新技能&#xff0c;可以帮助你的公司应对不断变化。包括人工智能、云平台应用、数据分析、 网络安全和体验设计。这些技能可以帮助你提高业务效率、保护公司知识资产、明智决策、满足客户需求并提高销售额。 现在就加…

Python入门到精通(三)——Python循环语句

Python循环语句 一、while 循环 1、基础语法 2、嵌套应用 二、for 循环 1、基础语法 2、嵌套应用 三、循环中断&#xff1a;break 和 continue 1、break 2、continue 四、综合案例 一、while 循环 1、基础语法 while的条件需得到布尔类型&#xff0c;True表示继续循环…

一款真正可用的支付系统,可搭建自己的易支付系统,开源无后门

应用介绍 介绍: thinkphp开发的风吹雪支付系统易支付去后台验证版本&#xff0c;支持代理系统&#xff0c;适合搭建易支付系统&#xff0c;完整100%可运行网站源码。是为数不多的一款真正可用的支付系统&#xff0c;开源无后门可运营。 自带微信支付宝官方通道&#xff0c;资质…

探秘网络爬虫的基本原理与实例应用

1. 基本原理 网络爬虫是一种用于自动化获取互联网信息的程序&#xff0c;其基本原理包括URL获取、HTTP请求、HTML解析、数据提取和数据存储等步骤。 URL获取&#xff1a; 确定需要访问的目标网页&#xff0c;通过人工指定、站点地图或之前的抓取结果获取URL。 HTTP请求&#…

一键拆分,轻松整理,高效管理文本文件,让工作更轻松!

在日常工作中&#xff0c;我们经常需要处理大量的文本文件。如何快速整理这些文件&#xff0c;方便管理和使用成为了关键问题。为此&#xff0c;我们为您推荐一款强大的一键拆分和整理工具&#xff0c;助您高效管理文本文件&#xff01; 首先&#xff0c;在首助编辑高手的主页面…

Gradle——基础

1、Gradle基础 1.1、Ant/Maven/Gradle对比 无论那种项目构建工具&#xff0c;都有自身的优势和劣势&#xff0c;所以选择一款最适合项目的就是最好的&#xff01; 1.2、Gradle项目目录结构 Gradle项目默认目录结构和Maven项目的目录结构一致&#xff0c;都是基于约定大于配置…

好物周刊#37:元气桌面

https://github.com/cunyu1943/JavaPark https://yuque.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. MallChat 一个既能购物又能聊天的电商系统。以互联网企业级开发规范的…

《斗罗大陆Ⅱ绝世唐门》美女盘点:高颜值角色吸睛无数,玄机科技再塑国漫辉煌

在国漫崛起的大潮中&#xff0c;玄机科技以其精湛的建模技术和独特的审美视角&#xff0c;打造了一部又一部备受瞩目的佳作。其中&#xff0c;《绝世唐门》作为玄幻类动画的代表&#xff0c;凭借其丰富的人物设定和颜值爆表的角色&#xff0c;赢得了无数观众的喜爱和追捧。今天…

DC-3靶机刷题记录

靶机下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1-P5ezyt5hUbmmGMP4EI7kw?pwdrt2c 提取码&#xff1a;rt2c 参考&#xff1a; http://t.csdnimg.cn/hhPi8https://www.vulnhub.com/entry/dc-32,312/ 官网http://t.csdnimg.cn/5mVZ7DC-3 (1).pdfhttps://…

裸辞后找工作有多难?分享个人经历+面经+学习路线【内含免费下载初级前端面试题】- 回忆我的2023

&#x1f449; 个人博客主页 &#x1f448; &#x1f4dd; 一个努力学习的程序猿 专栏&#xff1a; HTML和CSS JavaScript jQuery Vue Vue3 React TypeScript uni-app Linux 前端面试分享 前端学习方案分享(VitePress、html2canvasjspdf、vuedraggable、videojs) 前端踩坑日记&…

2023年上半年网络工程师真题(2/3)

21.在OSI参考模型中&#xff0c;负责对应用层消息进行压缩&#xff0c;加密功能的层次为&#xff08;C&#xff09;。 A.传输层 B.会话层 C.表示层 D.应用层 表示层。表示层处理的是用户信息的表示问题。端用户(应用进程)之间传送的数据包含语义和语法两个方面。语义是数据…

索引的概述和性能分析

索引index&#xff0c;是一种有序的数据结构&#xff0c;可以高效的获取数据&#xff0c;在数据库中维护着满足查找特定算法的数据结构&#xff0c;就是索引 无索引的情况&#xff0c;查询数据时会全表扫描&#xff0c;效率极低 索引结构 &#xff08;1&#xff09;二叉树&…

flink学习之水位线

什么是水位线 在事件时间语义下&#xff0c;我们不依赖系统时间&#xff0c;而是基于数据自带的时间戳去定义了一个时钟&#xff0c; 用来表示当前时间的进展。于是每个并行子任务都会有一个自己的逻辑时钟&#xff0c;它的前进是靠数 据的时间戳来驱动的。 我们可以把时钟也以…

Linux下MySQL用户管理、权限、密码

一、原理 MySQL的用户管理实质上是对用户表的管理&#xff0c;系统中的数据库mysql存在一张用户表&#xff08;user&#xff09;&#xff0c;所有的用户都在该表内&#xff0c;对用户的管里也就是对该表进行增删查改的操作。 show databases; 如图中的mysql数据库&#xff0c;…

Leetcode 用队列实现栈

题目&#xff1a; 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶。 int pop() 移除并…

2024/1/20 并查集

目录 并查集关键代码 亲戚 村村通 团伙&#xff08;新知识&#xff09; 并查集关键代码 返回祖宗节点路径压缩&#xff1a; int find(int x) {if(f[x]!x) f[x]find(f[x]);return f[x]; } 合并&#xff1a; void make(int x,int y) {int f1find(f[x]);int f2find(f[y]);…

69.使用Go标准库compress/gzip压缩数据存入Redis避免BigKey

文章目录 一&#xff1a;简介二&#xff1a;Go标准库compress/gzip包介绍ConstantsVariablestype Headertype Reader 三&#xff1a;代码实践1、压缩与解压工具包2、单元测试3、为何压缩后还要用base64编码 代码地址&#xff1a; https://gitee.com/lymgoforIT/golang-trick/t…

图像分割实战-系列教程15:deeplabV3+ VOC分割实战3-------网络结构1

&#x1f341;&#x1f341;&#x1f341;图像分割实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 deeplab系列算法概述 deeplabV3 VOC分割实战1 deeplabV3 VOC分割实战2 deeplabV3 VOC分割实战3 dee…

C#中chart控件

C#中chart控件 图表的5大集合 例子 第一步&#xff1a;创建工程 放入chart控件 series集合 选择图标类型 选择绘制曲线的宽度和颜色。 显示数据标签 Title集合 添加标题 调整标题字体&#xff1a;大小和颜色 CharsArea集合 对坐标轴进行说明 设置间隔 设置刻度…

使用Ultimate-SD-Upscale进行图片高清放大

之前我们介绍过StableSR进行图片高清放大&#xff0c;如果调的参数过大&#xff0c;就会出现内存不足的情况&#xff0c;今天我们介绍另外一个进行图片高清放大的神器Ultimate-SD-Upscale&#xff0c;他可以使用较小的内存对图像进行高清放大。下面我们来看看如何使用进行操作。…