• python基础27——反射&内置方法


    反射


    什么是反射?

    指的是在程序运行过程中可以"动态(不见棺材不掉泪)"获取对象的信息

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)

    什么是反射机制?

    反射机制指的是在程序的运行状态中

    对于任意一个类,都可以知道这个类的所有属性和方法

    对于任意一个对象,都能够调用他的任意方法和属性

    这种动态获取程序信息以及动态调用对象的功能称为反射机制

    为什么用反射?

    好处一:实现可插拔机制

    可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

    egon还没有实现全部功能
    
    class FtpClient:
        'ftp客户端,但是还么有实现具体的功能'
        def __init__(self,addr):
            print('正在连接服务器[%s]' %addr)
            self.addr=addr
    
    
    
    
    
    不影响lili的代码编写
    
    #from module import FtpClient
    f1=FtpClient('192.168.1.1')
    if hasattr(f1,'get'):
        func_get=getattr(f1,'get')
        func_get()
    else:
        print('---->不存在此方法')
        print('处理其他的逻辑')

    好处二:动态导入模块(基于反射当前模块成员)

    如何实现反射?

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

    def say(self):
      print('<%s:%s>' %(self.name,self.age))

      obj=People('辣白菜同学',18)

     

    实现反射机制的步骤

    1、先通过多dir:查看出某一个对象下可以.出哪些属性来
      print(dir(obj))

    >>> 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']

    2、可以通过字符串反射到真正的属性上,得到属性值
      print(obj.__dict__[dir(obj)[-2]])

    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)
    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

    四个内置函数的使用:通过字符串来操作属性值

    1、hasattr(object,name)        检测是否含有某属性

    判断object中有没有一个name字符串对应的方法或属性

     print(hasattr(obj,'name'))
     print(hasattr(obj,'x'))

    2、getattr(object, name, default=None)      获取属性

     print(getattr(obj,'name'))

    3、setattr(x,y,v)     设置属性

     setattr(obj,'name','EGON')           # obj.name='EGON'
     print(obj.name)

    4、delattr(x,y)    删除属性

     delattr(obj,'name') # del obj.name
     print(obj.__dict__)

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

    >>> class FtpServer:
    ...     def serve_forever(self):
    ...         while True:
    ...             inp=input('input your cmd>>: ').strip()
    ...             cmd,file=inp.split()
    ...             if hasattr(self,cmd): # 根据用户输入的cmd,判断对象self有无对应的方法属性
    ...                 func=getattr(self,cmd) # 根据字符串cmd,获取对象self对应的方法属性
    ...                 func(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...

    内置方法

    1、什么是内置方法?

    定义在类内部,以__开头并以__结果的方法
    特点:会在某种情况下自动触发执行

    2、为何要用内置方法?

    为了定制化我们的类or对象

    3、如何使用内置方法

     __str__:打印对象时会自动触发,然后将返回值(必须是字符串类型)当做本次打印的结果输出

    >>> 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
            self.x = open('a.txt',mode='w')
            # self.x = 占据的是操作系统资源
    
        def __del__(self):
            # print('run...')
            # 发起系统调用,告诉操作系统回收相关的系统资源
            self.x.close()
    
    obj = People('辣白菜同学', 18)
    # del obj # obj.__del__()
    print('============>')
  • 相关阅读:
    数据库设计:数据库设计步骤,er图,三大范式
    连接查询
    连接查询和分组查询
    Django项目的创建与配置
    WEB框架的原理总结
    RabbitMQ---消息队列
    Djang之基于角色的权限控制(RBAC)
    Django之基于RBAC权限控制生成动态菜单
    关于装饰器的一些小练习
    关于简单的python函数的一些小练习题
  • 原文地址:https://www.cnblogs.com/lucky-cat233/p/12706775.html
Copyright © 2020-2023  润新知