zoukankan      html  css  js  c++  java
  • day33---反射和内置方法

    一、什么是反射

    #反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。
    #这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

    python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    二、四个可以实现自省的函数

    适用于类和对象(python中一切皆对象,类也是一种对象)

    class Beast:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    b = Beast('姜春', 25)
    if hasattr(b,'name'):            #按字符串'name'判断有无属性b.name
        name = getattr(b,'name',None)  等同于b.name,不存在该属性则返回默认值None
        print(name)
    if hasattr(b, 'age'):
        print('{}'.format(getattr(b,'age',None)))
        setattr(b,'age',78)               # 等同于b.age = 78
        print('{}'.format(getattr(b,'age',None)))
    delattr(b,'age')                # 等同于del b.age
    print('{}'.format(getattr(b,'age',None)))
    class Beast:
        def __init__(self, name, age):
            self.name = name
            self.age = age
            self.score = {}
    
        def hello(self):
            print(f'hello,{self.name}')
    
        @property
        def show_score(self):
            return self.score
    
        @show_score.setter
        def show_score(self,score):
            self.score[score[0]] = score[1]
    
    
    b = Beast('姜春', 26)
    # 判断是否有某属性,获取属性
    if hasattr(b,'show_score'):
        if not getattr(b,'show_score','姜春就是一个瓜皮'):
            setattr(b,'show_score',['洗脚',100])
        print(getattr(b,'show_score'))
    # 设置属性
    setattr(b,'show_name',lambda self:self.name+'_DSB')
    print(getattr(b,'show_name')(b))
    
    # 删除属性
    delattr(b,'show_name')
    print(getattr(b,'show_name','姜春你就是一个瓜皮'))
    >>> 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...

    (2)导入其他模块,查看其他模块是否有某种方法

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    def test():
        print('from the test')
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3  
     4 """
     5 程序目录:
     6     module_test.py
     7     index.py
     8  
     9 当前文件:
    10     index.py
    11 """
    12 
    13 import module_test as obj
    14 
    15 #obj.test()
    16 
    17 print(hasattr(obj,'test'))
    18 
    19 getattr(obj,'test')()

    三、反射的好处

    1、实现可插拔机制

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

    2、动态导入模块

    import importlib
    
    m = importlib.import_module('test.practice7')  #绝对导入
    m = importlib.import_module('.practice7',package='test') # 相对导入

    四、内置方法

    (1)__str__

    __str__方法会在对象被打印时自动触发,print功能打印的就是它的返回值,我们通常基于方法来定制对象的打印信息,该方法必须返回字符串类型
    class FileOperate:
        """文件处理类"""
        def __init__(self,filename):
            self.filename = filenamedef __str__(self):
            return f'{self.filename}'
    
    F = FileOperate('3.txt')
    print(F)
    3.txt

    (2) __del__

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

    (3)__repr__

    使用方法同__str__

    str函数或者print函数--->obj.__str__()
    repr或者交互式解释器--->obj.__repr__()
    如果__str__没有被定义,那么就会使用__repr__来代替输出
    注意:这俩方法的返回值必须是字符串,否则抛出异常

    (4)__format__

    date_dic={
        'ymd':'{0.year}:{0.month}:{0.day}',
        'dmy':'{0.day}/{0.month}/{0.year}',
        'mdy':'{0.month}-{0.day}-{0.year}',
    }
    class Date:
        def __init__(self,year,month,day):
            self.year=year
            self.month=month
            self.day=day
    
        def __format__(self, format_spec):
            if not format_spec or format_spec not in date_dic:
                format_spec='ymd'
            fmt=date_dic[format_spec]
            return fmt.format(self)
    
    d1=Date(2016,12,29)
    print(format(d1))
    print(format(d1,'mdy'))
  • 相关阅读:
    java selenium (九) 常见web UI 元素操作 及API使用
    java selenium (六) XPath 定位
    java selenium (八) Selenium IDE 用法
    java selenium (五) 元素定位大全
    一个使用CSocket类的网络通信实例
    揭开链接器的面纱(中)
    揭开连接器的面纱(上)
    深入理解程序的结构
    调试利器GDB(下)
    调试利器GDB(上)
  • 原文地址:https://www.cnblogs.com/surpass123/p/12706936.html
Copyright © 2011-2022 走看看