在做程序开发中,我们常常会遇到这样的需求:需要执行对象里的某个方法,或需要调用对象中的某个变量,但是由于种种原因我们无法确定这个方法或变量是否存在,这是我们需要用一个特殊的方法或机制要访问和操作这个未知的方法或变量,这中机制就称之为反射

反射:用字符串的方式去访问对象的属性,调用对象的方法python中一切皆对象,都可以使用反射

  1. hasattr(obj, name):检查 obj 对象是否包含名为 name 的属性或方法。
  2. getattr(object, name[, default]):获取 object 对象中名为 name 的属性的属性值。
  3. setattr(obj, name, value,/):将obj 对象的 name 属性设为 value。

hasattr

判断一个对象是否有name属性或者name方法。有就返回True,没有就返回False

class Person(object):
    def __init__(self,name):
        self.name = name
    def talk(self):
        print("%s正在交谈"%self.name)

p = Person("santa")
print(hasattr(p,"talk"))    # True。因为存在talk方法
print(hasattr(p,"name"))    # True。因为存在name变量
print(hasattr(p,"abc"))     # False。因为不存在abc方法或变量

getattr

获取对象的属性或者方法,如果存在则打印出来。hasattrgetattr配套使用

class Person(object):
    def __init__(self,name):
        self.name = name
    def talk(self):
        print("%s正在交谈"%self.name)
p = Person("santa")

n = getattr(p,"name")   # 获取name变量的内存地址
print(n)                # 此时打印的是:laowang

f = getattr(p,"talk")   # 获取talk方法的内存地址
f()                     # 调用talk方法

# 我们发现getattr有三个参数,那么第三个参数是做什么用的呢?
s = getattr(p,"abc","not find")
print(s)
#若属性不存在,则返回默认值(第三个参数)

打印结果:

santa
santa正在交谈
not find

setattr

给对象的属性赋值,若属性不存在,先创建后赋值

def abc(self):
    print("%s正在交谈"%self.name)

class Person(object):
    def __init__(self,name):
        self.name = name

p = Person("santa")
setattr(p,"talk",abc)   # 将abc函数添加到对象中p中,并命名为talk
p.talk(p)               # 调用talk方法,因为这是额外添加的方法,需手动传入对象
#结果
#santa正在交谈
setattr(p,"age",30)     # 添加一个变量age,赋值为30
print(p.age)            # 打印结果:30

delattr

删除该对象指定的一个属性。注意:不能用于删除方法

class Person(object):
    def __init__(self,name):
        self.name = name
    def talk(self):
        print("%s正在交谈"%self.name)

p = Person("laowang")

delattr(p,"name")         # 删除name变量
print(hasattr(p,'name'))  #False

反射的应用

# 反射应用:
根据用户输入进行动态调用
class FileControl:

    def run(self):
        while True:
            # 让用户输入上传或下载功能的命令:
            user_input = input('请输入 上传(upload) 或 下载(download) 功能:').strip()

            # 通过用户输入的字符串判断方法是否存在,然后调用相应的方法
            if hasattr(self, user_input):
                func = getattr(self, user_input)
                func()
            else:
                print('输入有误!')

    def upload(self):
        print('文件正在上传...')

    def download(self):
        print('文件正在下载...')

file_control_obj = FileControl()
file_control_obj.run()

这就是python的反射,它的核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!

__import__(了解)

要是想导入不同目录下的函数,可以这样:动态导入模块

def run():
    inp = input("请输入您想访问页面的url:  ").strip()
    modles, func = inp.split("/")
    obj = __import__("lib." + modules, fromlist=True)  # 注意fromlist参数  modles是url
    if hasattr(obj, func):
        func = getattr(obj, func)
        func()
    else:
        print("404")

if __name__ == '__main__':
    run()

思考:

可能有人会问python不是有两个内置函数exec和eval吗?他们同样能够执行字符串。比如:

exec("print('haha')")
结果:
haha

那么直接使用它们不行吗?非要那么费劲地使用getattr,__import__干嘛?

其实,在上面的例子中,围绕的核心主题是如何利用字符串驱动不同的事件,比如导入模块、调用函数等等,这些都是python的反射机制,是一种编程方法、设计模式的体现,凝聚了高内聚、松耦合的编程思想,不能简单的用执行字符串来代替。当然,exec和eval也有它的舞台,在web框架里也经常被使用。

hasattr、getattr、setattr、delattr、反射的更多相关文章

  1. hasattr getattr setattr delattr --> (反射)

    class Room: def __init__(self,name): self.name = name def big_room(self): print('bigroot') R = Room( ...

  2. isinstance/type/issubclass的用法,反射(hasattr,getattr,setattr,delattr)

    6.23 自我总结 面向对象的高阶 1.isinstance/type/issubclass 1.type 显示对象的类,但是不会显示他的父类 2.isinstance 会显示的对象的类,也会去找对象 ...

  3. python 内置函数的补充 isinstance,issubclass, hasattr ,getattr, setattr, delattr,str,del 用法,以及元类

    isinstance   是 python中的内置函数 , isinstance()用来判断一个函数是不是一个类型 issubclass  是python 中的内置函数,  用来一个类A是不是另外一个 ...

  4. python反射hasattr getattr setattr delattr

    反射 : 是用字符串类型的名字 去操作 变量 相比于用eval('print(name)') 留有 安全隐患 反射 就没有安全问题 hasattr 语法: hasattr(object, name)o ...

  5. Python hasattr,getattr,setattr,delattr

    #!/usr/bin/env python # -*- coding:utf-8 -*- # 作者:Presley # 邮箱:1209989516@qq.com # 时间:2018-11-04 # 反 ...

  6. 反射hasattr; getattr; setattr; delattr

    hasattr(obj,name_str):#判断一个对象obj里面是否有对应的name_str字符串的方法,返回True或者Falsegetattr(obj,name_str):#根据字符串去获取对 ...

  7. python动态函数hasattr,getattr,setattr,delattr

    hasattr(object,name) hasattr用来判断对象中是否有name属性或者name方法,如果有,染回true,否则返回false class attr():     def fun( ...

  8. Python的getattr(),setattr(),delattr(),hasattr()及类内建__getattr__应用

    @Python的getattr(),setattr(),delattr(),hasattr() 先转一篇博文,参考.最后再给出一个例子 getattr()函数是Python自省的核心函数,具体使用大体 ...

  9. 反射之hasattr() getattr() setattr() 函数

    Python的hasattr() getattr() setattr() 函数使用方法详解 hasattr(object, name)判断object中有没有一个name字符串对应的方法或属性,返回B ...

  10. 【转】Python的hasattr() getattr() setattr() 函数使用方法详解

    Python的hasattr() getattr() setattr() 函数使用方法详解 hasattr(object, name)判断一个对象里面是否有name属性或者name方法,返回BOOL值 ...

随机推荐

  1. Java入门程序HelloWorld

    程序开发步骤说明 开发环境已经搭建完毕,可以开发我们第一个Java程序了.Java程序开发三步骤:编写.编译.运行.如下图所示 详解: 编写源程序:通俗来说就是我们通过Java的语法自己写的代码 编译 ...

  2. Servlet一次乱码排查后的总结

    由来 在写一个小小的表单提交功能的时候,出现了乱码,很奇怪request上来的参数全部是乱码,而从数据库查询出来的中文显示到页面正常,锁定肯定是request对象那里出了问题.后来经过排查,发现是我封 ...

  3. golang和swoole区别

    golang和swoole区别 开发效率 Go语言是本质上是静态语言,开发效率稍差,但性能更强,更适合底层软件的开发 Swoole使用PHP语言,动态脚本语言,开发效率最佳,更适合应用软件的开发 IO ...

  4. Have a look ^_^

    参考书籍: <重构 改善既有代码的设计 第2版>马丁 福勒著 人民邮电出版社 马丁 福勒的其他著作:<分析模式>,<UML精粹>,<领域特定语言> 目录 ...

  5. 【转】理解ASP.NET Core验证模型(Claim, ClaimsIdentity, ClaimsPrincipal)不得不读的英文博文

    这篇英文博文是 Andrew Lock 写的 Introduction to Authentication with ASP.NET Core . 以下是简单的阅读笔记: -------------- ...

  6. 恢复Chrome 78以上版本的地址栏https和www显示

    Google在Chrome不知道是脑子抽抽还是怎么回事,非要把https://www从地址栏中隐藏掉. htttps://www.pool.ntp.org就给你显示个pool.ntp.org,这分明就 ...

  7. Think in Speed (关于速度的一点思考)

    天下武功,无坚不摧,唯快不破!所以我们重视速度没毛病! 老话说:不要过早优化.赞同! 我们在写代码过程中,有时可能就是为了追求所谓的性能,然后,就给自己挖坑了. 关于开发速度,我有以下几点思考: 1. ...

  8. Web前端——Html常用标签及属性

    html 常用的标题等标签就不记录了,只记录一下比较少见的标签以及属性 表格 table td 单元格 tr 表的行 th 表头 td或th可以下面的两个属性达到跨行或跨列 表格跨行 rowspan ...

  9. python3 对list对象的增删改查

    class peoples: people_list =[] class people: name='' age=-1 def __init__(self,name,age): self.name = ...

  10. MySQL入门——MySQL数据库和SQL语言

    MySQL入门——MySQL数据库和SQL语言 摘要:本文主要了解了MySQL关系型数据库和SQL语言的基本知识. MySQL数据库 简介 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB ...