zoukankan      html  css  js  c++  java
  • Python自动化开发

    本节内容

    1、isinstance(obj,cls)和issubclass(sub,super)

    2、反射

    3、__setattr__,__delattr__,__getattr__

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

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

    class Foo(object):
        pass
    
    obj = Foo()
    print(isinstance(obj, Foo))   # True

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

    class Foo(object):
        pass
    
    class Bar(Foo):
        pass
    
    print(issubclass(Bar, Foo))   # 必须是类,而不是实例
    
    二、反射

     

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

    这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

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

    四个可以实现自省的函数

    下列方法适用于类和对象(一切皆对象,类本身也是一个对象)。以object为例,同样适用于class

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

    getattr(object, name, None)   # 获取object中name字符串对应的方法或属性,没有则返回None

    setattr(object, name, value)   # 设置object中name字符串对应的值,无name时,新增属性

    delattr(oject, name)               # 删除ojbect中name字符对应的方法或属性,无name时会报错

    class BlackMedia(object):
        feature = "business"
    
        def __init__(self, name, address):
            self.name = name
            self.address = address
    
        def sell_house(self):
            print("我是黑中介[%s], 来买房吧!" % self.name)
    
        def rent_house(self):
            print("我是黑中介[%s], 来租房吧!" % self.name)
    
    b1 = BlackMedia("华夏地产", "皇城边上")
    
    # 检测是否含有某属性
    print(hasattr(b1, 'name'))         # 其中 'name' 为字符串****
    print(hasattr(b1, 'sell_house'))  # True
    
    # 获取属性
    n = getattr(b1, 'name')
    print(n)
    func = getattr(b1, 'rent_house')
    print(func)   # <bound method BlackMedia.rent_house of <__main__.BlackMedia object at 0x0000008F538344E0>>
    func()
    
    # getattr(b1, 'aaaaa')  不存在就报错
    print(getattr(b1, 'aaaa', '不存在'))
    
    # 设置属性
    setattr(b1, 'sb', True)
    setattr(b1, 'show_name', lambda self: self.name + '黑地产')
    print(b1.__dict__)
    print(b1.show_name(b1))
    
    # 删除属性
    delattr(b1, 'sb')
    # delattr(b1, 'show_name11')  没有就报错
    print(b1.__dict__)
    四个方式使用示例
    class Foo(object):
        staticField = "old boy"
    
        def __init__(self):
            self.name = 'wupeiqi'
    
        def func(self):
            return 'func'
    
        @staticmethod
        def bar():
            return 'bar'
    
    
    print(getattr(Foo, 'staticField'))
    print(getattr(Foo, 'func'))
    print(getattr(Foo, 'bar'))
    类也是对象

    3、反射的好处

    好处一: 可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’

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

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

    三、__setattr__,__delattr__,__getattr__

     

    class Foo:
        x=1
        def __init__(self,y):
            self.y=y
    
        def __getattr__(self, item):
            print('----> from getattr:你找的属性不存在')
    
    
        def __setattr__(self, key, value):
            print('----> from setattr')
            # self.key=value #这就无限递归了,你好好想想
            # self.__dict__[key]=value #应该使用它
    
        def __delattr__(self, item):
            print('----> from delattr')
            # del self.item #无限递归了
            self.__dict__.pop(item)
    
    #__setattr__添加/修改属性会触发它的执行
    f1=Foo(10)
    print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
    f1.z=3
    print(f1.__dict__)
    
    #__delattr__删除属性的时候会触发
    f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
    del f1.a
    print(f1.__dict__)
    
    #__getattr__只有在使用点调用属性且属性不存在的时候才会触发
    f1.xxxxxx
    
    三者的用法演示
    三者用法演示
  • 相关阅读:
    EL表达式与JSTL
    jsp
    Servlet 会话
    Servlet 常用类
    Servlet
    Java 网络编程
    CentOS系统下安装python3+Django
    转载Alpine Linux常用命令
    转载Alpine基础
    CentOS启动docker1.13失败(Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.)
  • 原文地址:https://www.cnblogs.com/jonathan1314/p/6509061.html
Copyright © 2011-2022 走看看