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

反射:用字符串的方式去访问对象的属性,调用对象的方法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. As Simple as One and Two

    time limit per test3 secondsmemory limit per test256 megabytesinput: standard inputoutput: standard ...

  2. Fira Code:适合程序员的编程字体

    #Fira Code Fira 是 Mozilla 公司 主推的字体系列.Fira Code 是其中的一员,专为写程序而生.出来具有等宽等基本属性外,还加入了编程连字特性(ligatures). Fi ...

  3. SqlServer PIVOT行转列

    PIVOT通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合. 测试数据 INSERT INTO [TestRows2Columns] ...

  4. 拎壶学python3-----(2)python之if语句用法

    在生活中我们经常遇到各种选择,比如玩色子,猜大小,再比如选择未来另一半.python也经常会遇到这样的选择,这时候if语句显得尤为重要. 下边我们看一个简单的例子 如果是二选一怎么做呢?如下 如果多个 ...

  5. Spring Session工作原理

    本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/KCOFv0nRuymkX79-RZi9eg 作者:张正林 目录:1.引入背景2.使用方法3.工作流程 ...

  6. gRPC+gRPC Gateway+swagger小记

    前言 本文记录了grpc-gateway的简单使用. 定义proto 先来看看最常规的 syntax = "proto3"; package protos; service Gre ...

  7. Linux中的buff/cache内存

    我们用free.top等相关能够查询到当前内存的使用情况的命令时,总会有一个buff/cache让我们很困惑. buffer 即写如磁盘时,先保存到磁盘缓冲区(buffer),然后再写入到磁盘. ca ...

  8. MySQL 中的索引

    索引用来加速查询.正常来说,当查询数据时,MySQL 需要从表的第一条记录开始,读取整个表的内容,进行查询. 但如果有索引,MySQL 可根据索引快速定位需要查询条目的具体位置,加快了查询速度. 原理 ...

  9. python基础(24):面向对象三大特性一(继承)

    1. 继承 1.1 什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类. python中类的继承分为:单继承和多继 ...

  10. Winform中自定义ZedGraph右键复制成功后的提示

    场景 Winform中实现ZedGraph中曲线右键显示为中文: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100115292 ...