Python--面向对象之反射与魔法方法

一、反射

在Python中,反射指的是通过字符串来操作对象的属性,涉及到四个内置函数的使用

hasattr( ):判断对象是否含有字符串对应的功能或数据

getattr( ):根据字符串获取对应的变量名或者函数名

setattr( ):根据字符串给对象设置键值对( 名称空间的名字 )

delattr( ):根据字符串删除对象对应的键值对( 名称空间的名字 )

Python中一切皆对象,类和对象都可以用下述四个方法

在python中实现反射非常简单,在程序运行过程中,如果我们获取一个不知道存有何种属性的对象,若想操作其内部属性,可以先通过内置函数dir来获取任意一个类或者对象的属性列表,列表中全为字符串格式

class People:
    def __init__(self,name,age,gender):
        self.name=name
        self.age=age
        self.gender=gender

obj=People('egon',18,'male')
dir(obj) # 列表中查看到的属性全为字符串
[......,'age', 'gender', 'name']

接下来就是想办法通过字符串来操作对象的属性了,这就涉及到内置函数hasattr、getattr、setattr、delattr的使用了(Python中一切皆对象,类和对象都可以用下述四个方法)

class Teacher:
    def __init__(self,full_name):
        self.full_name =full_name

t=Teacher('jason Lin')

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

# getattr(object, 'name', default=None)
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 Wincmd:
    def ls(self):
        print('windows running -----ls')

    def dir(self):
        print('windows running -----dif')

class Linuxcmd:
    def ls(self):
        print('Linux running -----ls')

    def dir(self):
        print('Linux running -----dif')

def run(obj):
    while True:
        cmd = input('your command:').strip()
        if hasattr(obj,cmd):
            func_name = getattr(obj,cmd)
            func_name()
            break
        else:
            print('cmd command not found')
            break


win = Wincmd()
lin = Linuxcmd()

if __name__ == '__main__':
    run(win)

二、魔法方法

魔法方法其实就是在某种条件下回自动触发执行的方法,一般的结构就是 _ _ xxxx _ _, 有双下划线的方法

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

__str__方法会在对象被打印时自动触发,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>

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

class People:
    def __init__(self,name,age):
      self.name=name
      self.age=age
    
    def __del__(self):
      print("=======>")
  
obj = People('fuank',19)
del obj # 在对象obj被删除时,自动触发obj.__del__()
print('end')

"""
=======>
end
"""
class People:
    def __init__(self,name,age):
      self.name=name
      self.age=age
    
    def __del__(self):
      print("=======>")
  
obj = People('fuank',19)

print('end')
# 垃圾回收机制会自动删除 obj,触发 del obj

"""
end
=======>
"""

常用的魔法方法补充

__getattr__ : 对象查找不存在名字的时候自动触发

__setattr__ : 对象在执行添加属性操作的时候自动触发 >>> obj.变量名=变量值

__call__ : 对象被加括号调用的时候自动触发

​ 参考元类的介绍---->元类

__enter__ :
对象被执行with上下文管理语法开始自动触发
该方法返回什么 as 后面的 变量名 就会得到什么

__exit__ : 对象被执行with上下文管理语法结束之后自动触发

__getattribute__ : 只要对象查找名字无论名字是否存在都会执行该方法
如果类中有__getattribute__方法 那么就不会去执行__getattr__方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值