31类和对象-----反射(hasattr/getattr/setattr/delattr)

参考https://www.cnblogs.com/linhaifeng/articles/6204014.html

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

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

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

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.
    """

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

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

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

 4、使用例子1

class Black:
    feature = 'ugly'
    def __init__(self, name, addr):
        self.name = name
        self.addr = addr
    def sell_h(self):
        print('{} sell_h....'.format(self.name))
    def rent_h(self):
        print('{} rent_h....'.format(self.name))

b1 = Black('kkkk', '北京123')

# 检测是否含有属性.类也可以检测
print(hasattr(Black,'feature'))
print(hasattr(Black,'sell_h'))
print(hasattr(b1,'sell_h'))
print(hasattr(b1, 'name'))

# 获取属性
n = getattr(b1, 'name')
print(n)
func = getattr(b1,'rent_h')
func()

# 设置属性
setattr(b1,'name','mmm')
print(b1.name)
setattr(b1,'age',14)
print(b1.age)
print(b1.__dict__)

# 删除属性
delattr(b1, 'name')
print(b1.__dict__)

 

 5、例子2

# 反射当前模块成员
import sys
def s1():
    print('s1')

def s2():
    print('s2')

this_moudle = sys.modules[__name__]#所有加载到内存的模块都放在sys.modules,不知道的话可以打印一下看看
print(hasattr(this_moudle, 's1'))
f = getattr(this_moudle, 's2')
f()

 

6、例子3

# 导入其他模块,利用反射查找该模块是否存在某个方法
import test as t

print(hasattr(t,'test'))
f = getattr(t,'test')
f()

 

7、 反射的一个好处:

  两个程序员A B,A写程序的时候要用到B的类,但B不在,这时候可以用反射,A可以继续写自己的代码

# 下面是B的程序
class FtpClient:
    def __init__(self, addr):
        print('正在连接服务器。。。。')
        self.addr = addr

# 下面是A的程序
f = FtpClient('192.168.1.1')
if hasattr(f, 'get'):
    func_get = getattr(f, 'get')
    func_get()
else:
    print('不存在这个方法')
    print('处理其他逻辑')

 

8、基于反射实现动态导入模块,像字符串一样调用(这里没有仔细看)

this_moudle = __import__('test')

import importlib
this_moudle = importlib.import_module('test')
this_moudle.test()

 

posted @ 2021-04-05 15:08  cheng4632  阅读(153)  评论(0编辑  收藏  举报