Python中的反射?

在反射机制就是在运行时,动态的确定对象的类型,并可以通过字符串调用对象属性、方法、导入模块,是一种基于字符串的事件驱动。通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员。

Python是一门解释型语言,因此对于反射机制支持很好。在Python中支持反射机制的函数有getattr()、setattr()、delattr()、exec()、eval()、__import__,这些函数都可以执行字符串。

反射,reflection,指的是运行时获取类型定义信息。
一个对象能够在运行时,像照镜子一样,反射出其类型信息。简单说,在Python中,能够通过一个对象,找出其type、class、attribute或method的能力,称为反射或自省。
具有反射能力的函数有type(),isinstance(),callable().dir().getattr()等

在 Python 中,反射的实现很简单,主要通过以下 4 个函数:

getattr()

# getattr 语法
getattr(object,name[,default])
 
#参数
# · object -- 对象
# · name -- 字符串,对象属性
# · default-- 默认返回值,如果不提供该参数,在没有对应属性时,将触发AttrbuteError.
 
# 返回值 :返回对象属性值
class test():
    name="david"
    def run(self):
        return "Hello David"
t=test()        # t 为一个test对象
getattr(t, "name") #获取name属性
getattr(t, "run")  #获取run方法,存在就打印出方法的内存地址。
<bound method test.run of <__main__.test instance at 0x0269C878>>
getattr(t, "run")()  #获取run方法,后面加括号可以将这个方法运行。
'Hello David'
getattr(t, "david")  #获取一个不存在的属性。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: test instance has no attribute 'david'
getattr(t, "david","18")  #若属性不存在,返回一个默认值。
'18'


hasattr()

# hasattr 语法
hasattr(object,name)
 
#参数
# · object -- 对象
# · name -- 字符串,属性名
 
# 返回值 :如果对象有该属性返回 True,否则返回 False。

t=test()           # test 还是上面的那个
hasattr(t, "name") #判断对象有name属性
True
hasattr(t, "run")  #判断对象有run方法
True

setattr()

# setattr 语法
setattr(object, name, value)
 
#参数
# · object -- 对象
# · name -- 字符串,属性名
# · value -- 属性值。
 
# 返回值 :无
>>> t=test()
>>> hasattr(t, "hdw")   #判断属性是否存在
False
>>> setattr(t, "hdw", "18")   #为属相赋值,并没有返回值
>>> hasattr(t, "hdw")    #属性存在了
True

delattr()

delattr(object, name)

delattr() 函数用来删除指定对象的指定名称的属性,和setattr函数作用相反,属性必须存在,否则发出AttributeError。

This is a relative of setattr(). The arguments are an object and a string. The string must be the name of one of the object’s attributes. The function deletes the named attribute, provided the object allows it. For example, delattr(x, 'foobar') is equivalent to del x.foobar.
#定义类A
class A:
    def __init__(self,name):
        self.name = name
    def sayHello(self):
        print('hello',self.name)
A a;    # a是一个A对象
#测试属性和方法
a.name
'小麦'
a.sayHello()
hello 小麦
 
#删除属性
>>> delattr(a,'name')
>>> a.name
Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    a.name
AttributeError: 'A' object has no attribute 'name'

>>> a.name #属性name已经删掉,不存在
Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    a.name
AttributeError: 'A' object has no attribute 'name'
 
>>> delattr(a,'name') #再删除会报错
Traceback (most recent call last):
  File "<pyshell#48>", line 1, in <module>
    delattr(a,'name')
AttributeError: name

>>> a.sayHello
<bound method A.sayHello of <__main__.A object at 0x03F014B0>>
>>> delattr(a,'sayHello') #不能用于删除方法
Traceback (most recent call last):
  File "<pyshell#50>", line 1, in <module>
    delattr(a,'sayHello')
AttributeError: sayHello
>>>
平常可能需要用到上面的四个函数。

r = hasattr(commons,xxx)             # 判断某个函数或者变量是否存在
print(r)  
 
setattr(commons,'age',18)            # 给commons模块增加一个全局变量age = 18,创建成功返回none
 
setattr(config,'age',lambda  a:a+1)  # 给模块添加一个函数
 
delattr(commons,'age')               # 删除模块中某个变量或者函数
注:getattr,hasattr,setattr,delattr对模块的修改都在内存中进行,并不会影响文件中真实内容。

注:getattr,hasattr,setattr,delattr对模块的修改都在内存中进行,并不会影响文件中真实内容。

反射机制常常都是使用在web框架上,比如你浏览某个网页,你点网页上的文字或则图片,则会跳转或者说生成新的页面,这是怎么实现的呢?就是采用反射机制实现的,当你点击某个东西是不是就对应不同的url,而url是字符串的形式,穿进去,就可以通过那几个函数找到对应的实现方法

赞(1) 打赏
特别声明:除特殊标注,本站文章均为原创,遵循CC BY-NC 3.0,转载请注明出处。三伏磨 » Python中的反射?

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏