• python基础之类的isinstance与issubclass、反射


    一 isinstance(obj,cls)和issubclass(sub,super)

    isinstance(obj,cls)检查是否obj是否是类 cls 的对象

    class Foo:
        pass
    
    obj = Foo()
    
    print(isinstance(obj,Foo))

    issubclass(sub, super)检查sub类是否是 super 类的派生类

    class Foo:
        pass
    
    class Bar(Foo):
        pass
    
    print(issubclass(Bar,Foo))
    

    二 反射

    1、什么是反射
    主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。

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

    • 基于对象级别的反射
    • 基于类级别的反射
    • 基于模块级别的反射

    四个可以实现自省的函数:

    def hasattr(*args, **kwargs): # real signature unknown
        """
        Return whether the object has an attribute with the given name.
        
        This is done by calling getattr(obj, name) and catching AttributeError.
        """
        pass
    #检测是否含有某属性
    hasattr(object,name)
    def getattr(object, name, default=None): # known special case of getattr
        """
        getattr(object, name[, default]) -> value
        
        Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
        When a default argument is given, it is returned when the attribute doesn't
        exist; without it, an exception is raised in that case.
        """
        pass
    #获取属性
    getattr(object, name, default=None)
    def setattr(x, y, v): # real signature unknown; restored from __doc__
        """
        Sets the named attribute on the given object to the specified value.
        
        setattr(x, 'y', v) is equivalent to ``x.y = v''
        """
        pass
    #设置属性
    setattr(x, y, v)
    def delattr(x, y): # real signature unknown; restored from __doc__
        """
        Deletes the named attribute from the given object.
        
        delattr(x, 'y') is equivalent to ``del x.y''
        """
        pass
    #删除属性
    delattr(x, y)

    使用演示:

    class People:
        country='China'
        def __init__(self,name):
            self.name=name
        def walk(self):
            print('%s is walking'%self.name)
    p=People('egon')
    
    print(People.__dict__)
    print(p.name)
    print(p.__dict__)
    
    #----------------------
    
    #hasattr
    print('name' in p.__dict__)
    print(hasattr(p,'name'))
    print(hasattr(p,'name1213'))
    
    print(hasattr(p,'country')) #p.country  #基于对象
    print(hasattr(People,'country')) #People.country #基于类
    print(hasattr(People,'__init__')) #People.__init__
    
    #----------------------
    
    #getattr
    res=getattr(p,'country') #res=p.country
    print(res)
    
    f=getattr(p,'walk') #t=p.walk
    print(f)
    
    f1=getattr(People,'walk')
    print(f1)
    
    f()
    f1(p)
    
    print(p.xxxxxxx)
    print(getattr(p,'xxxxxxxx','这个属性确实不存在'))
    
    
    if hasattr(p,'walk'):
        func=getattr(p,'walk')
        func()
    
    print('================>')
    print('================>')
    
    
    #----------------------
    
    #setattr
    p.sex='male'
    print(p.sex)
    print(p.__dict__)
    
    setattr(p,'age',18)
    print(p.__dict__)
    print(p.age)
    print(getattr(p,'age'))
    四大金刚
    #反射当前模块的属性
    import sys
    
    x=1111
    class Foo:
        pass
    def s1():
        print('s1')
    
    def s2():
        print('s2')
    
    # print(__name__)
    
    this_module = sys.modules[__name__]
    print(this_module)
    
    print(hasattr(this_module, 's1'))
    print(getattr(this_module, 's2'))
    print(this_module.s2)
    print(this_module.s1)
    大力丸

    模块补充:

    __name__可以区别文件的用途:

    • 一种用途是直接运行文件,这叫把文件当成脚本运行。
    • 一种用途是不运行文件,在另一个文件中导入这个模块。

    3、反射的用途

    import sys
    def add():
        print('add')
    
    def change():
        print('change')
    
    def search():
        print('search')
    
    
    def delete():
        print('delete')
    
    func_dic={
        'add':add,
        'change':change,
        'search':search,
        'delete':delete
    }
    
    
    while True:
        cmd=input('>>:').strip()
        if not cmd:continue
        if cmd in func_dic: #hasattr()
            func=func_dic.get(cmd) #func=getattr()
            func()
    实例一
    import sys
    def add():
        print('add')
    
    def change():
        print('change')
    
    def search():
        print('search')
    
    
    def delete():
        print('delete')
    
    this_module=sys.modules[__name__]
    while True:
        cmd=input('>>:').strip()
        if not cmd:continue
        if hasattr(this_module,cmd):
            func=getattr(this_module,cmd)
            func()
    使用反射来实现:实例一

    好处一:实现可插拔机制

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

    模拟FTP功能:

    class FtpClient:
        'ftp客户端,但是还么有实现具体的功能'
        def __init__(self,addr):
            print('正在连接服务器[%s]' %addr)
            self.addr=addr
        def test(self):
            print('test')
        def get(self):
            print('get------->')
    ftpclient.py
    import ftpclient
    
    # print(ftpclient)
    # print(ftpclient.FtpClient)
    # obj=ftpclient.FtpClient('192.168.1.3')
    
    # print(obj)
    # obj.test()
    
    f1=ftpclient.FtpClient('192.168.1.1')
    if hasattr(f1,'get'):
        func=getattr(f1,'get')
        func()
    else:
        print('-->不存在此方法')
        print('其他逻辑')
    ftpserver.py

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

    # m=input("请输入你要导入的模块:")
    
    # m1=__import__(m)
    # print(m1)
    # print(m1.time())
    
    #推荐使用方法
    import importlib
    t=importlib.import_module('time')
    print(t.time())
    通过字符串导入模块
  • 相关阅读:
    【转】异或
    【算法习题】正整数数组中和为sum的任意个数的组合数
    mysql通过now()获取的时间不对
    【转】CentOS 7系统时间与实际时间差8个小时
    【算法习题】数组中任意2个(3个)数的和为sum的组合
    linux编译安装python3和安装django
    linux常见命令2
    解决安装centos的时候忘记打开网络的问题
    linux常见命令
    python3X和python2X的区别
  • 原文地址:https://www.cnblogs.com/luchuangao/p/6757852.html
Copyright © 2020-2023  润新知