python基础(二十七):反射与内置方法

下面是小凰凰的简介,看下吧!
💗人生态度:珍惜时间,渴望学习,热爱音乐,把握命运,享受生活
💗学习技能:网络 -> 云计算运维 -> python全栈( 当前正在学习中)
💗您的点赞、收藏、关注是对博主创作的最大鼓励,在此谢过!
有相关技能问题可以写在下方评论区,我们一起学习,一起进步。
后期会不断更新python全栈学习笔记,秉着质量博文为原则,写好每一篇博文。

一、反射

1、引言

首先假设我们要搞一个程序项目对接,对方向你扔过来了一个对象数据,但是他并不会告诉你这个对象数据有哪些数据属性、函数属性,如果试的话就会出现报错的情况。我们怎样解决这种情况呢?这就要用到反射了,然而说反射之前,我先说下动态语言这一概念!

python是一门动态语言,如何理解?

答:举个例子,python:x = 10,java: int x = 10# 这就是动态语言与静态语言的区别,python这句代码,程序只有在执行的时候,你才知道它是整型还是啥,因此python是动态语言。然而java在定义时就指明了类型,因此它是静态语言。

# 注意:我听有人说反射机制对动态语言很重要,静态语言好多都没有。但是我感觉有无反射,这应该与动态还是静态并没有什么联系。
2、根据现有知识实现反射机制(反射应用的具体场景)
>>> class People:
...     def __init__(self,name,age,gender):
...         self.name=name
...         self.age=age
...         self.gender=gender
>>> obj=People('egon',18,'male')
>>> dir(obj) # 下面全是obj这个对象能'.'出来的属性,它们全为字符串
[......,'age', 'gender', 'name']
# 假如我们程序对接需要obj这个对象的name属性
>>> obj.dir(obj)[-1] # 相当于obj.'name',这个可以这样吗,显然是不行的。
# ---- 怎么办?-----
>>> obj.__dict__[dir(obj)[-1]] # 这样我们就实现了反射,但是这样太复杂了,我们有专门的方法,更简单的实现反射!
'egon'
3、采用反射机制的专用方法实现反射
class Teacher:
    def __init__(self,full_name):
        self.full_name =full_name

t=Teacher('Egon Lin')

# hasattr(object,'name')
hasattr(t,'full_name') # 按字符串'full_name'判断有无属性t.full_name

# getattr(object, 'name', default=None),存在则返回名为'full_name'的方法
getattr(t,'full_name',None) # 等同于t.full_name,不存在该属性则返回默认值None

# setattr(x, 'y', v)
setattr(t,'age',18) # 等同于t.age=18

# delattr(x, 'y')
delattr(t,'age') # 等同于del t.age

基于反射可以十分灵活地操作对象的属性,比如将用户交互的结果反射到具体的功能执行

>>> class FtpServer:
...     def serve_forever(self):
...         while True:
...             inp=input('input your cmd>>: ').strip()
...             cmd,file=inp.split() # 看下下方的输入,就明白了为什么cmd,file
...             if hasattr(self,cmd): # 根据用户输入的cmd,判断对象self有无对应的方法属性
...                 func=getattr(self,cmd) # 根据字符串cmd,获取对象self对应的方法属性
...                 func(file) # 上面这句代码等同于sever.去掉字符串的cmd,因此还需要传参file
...     def get(self,file):
...         print('Downloading %s...' %file)
...     def put(self,file):
...         print('Uploading %s...' %file)
... 
>>> server=FtpServer()
>>> server.serve_forever()
input your cmd>>: get a.txt
Downloading a.txt...
input your cmd>>: put a.txt
Uploading a.txt...

二、内置方法

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

1、__str__

__str__方法会在对象被print打印时自动触发,即是说print功能打印就调用的是这个方法,并打印这个方法的返回值,我们通常基于方法来定制对象的打印信息,该方法必须返回字符串类型

>>> class People:
...     def __init__(self,name,age):
...         self.name=name
...         self.age=age
...     def __str__(self):
...         return '<Name:%s Age:%s>' %(self.name,self.age) #返回类型必须是字符串
... 
>>> p=People('lili',18)
>>> print(p) #触发p.__str__(),拿到返回值后进行打印
<Name:lili Age:18>

如果不定制的话就会打印对象的内存地址,我们要内存地址有什么用?因此我们通过str定制,打印对象时,打印我们想看到的有用信息。

2、__del__

__del__会在对象被删除时自动触发。由于Python自带的垃圾回收机制会自动清理Python程序的资源,所以当一个对象只占用应用程序级资源时,完全没必要为对象定制__del__方法,但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下,关于系统资源的回收,Python的垃圾回收机制便派不上用场了,需要我们为对象定制__del__方法,用来在对象被删除时,自动触发回收系统资源的操作

# 这里我们用打开文件为例,使其回收打开文件占用的内存资源
class MySQL:
    def __init__(self):
        self.read_f=open ('a.txt',mode = 'r') # 打开文件
    def __del__(self):
        self.read_f.close() # 关闭文件,回收系统内存资源

obj=MySQL() # 在对象obj被删除时,自动触发obj.__del__()

对象被删除有两种情况:

  • 执行del obj代码,主动删除
  • 程序运行完毕,全部对象都被删除
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凤求凰的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值