`

Python之反射

阅读更多

     一、引言

  有时候我们会碰到类似这样的需求,就是想要执行类的某个方法,或者需要对对象的某个参数赋值,而方法名或参数名已经包装在类中并不能去顶,需要通过参数传递字符串的形式输入。在这样的情况你会选择什么样的办法来解决吗?例如:

复制代码
#!/usr/bin/env python
# -*- coding=utf-8 -*-

class Action(object):
    def dog(self):
        print("汪汪汪")
    def cat(self):
        print("喵喵喵")

if __name__ == "__main__":
    animal = raw_input("Please write you want the animals:")
    act = Action()
    if animal == "dog":
        act.dog()
    elif animal == "cat":
        act.cat()
执行结果如下:
"D:\Program Files (x86)\Python27\python.exe" F:/Python/Alex/s12/Blog/reflect.py
Please write you want the animals:cat
喵喵喵
复制代码

在上面的代码中使用if语句的话,就是你每写一个方法就得有一个elif语句来判断,假如有1000个方法,这样就得有1000个elif语句。这么看是不是弱爆了。那么我们就来改写上面的代码:

复制代码
#!/usr/bin/env python
# -*- coding=utf-8 -*-

class Action(object):
    def dog(self):
        print("汪汪汪")
    def cat(self):
        print("喵喵喵")

if __name__ == "__main__":
    animal = raw_input("Please write you want the animals:")
    act = Action()
    if hasattr(act,animal):
        func = getattr(act,animal)
        func()
    else:
        print("You write the animal is not existed !")

执行结果如下:
"D:\Program Files (x86)\Python27\python.exe" F:/Python/Alex/s12/Blog/reflect.py
Please write you want the animals:cat
喵喵喵

"D:\Program Files (x86)\Python27\python.exe" F:/Python/Alex/s12/Blog/reflect.py
Please write you want the animals:snake
You write the animal is not existed !
复制代码

在这里使用到了hasattr()和getattr()两个python的内建函数。通俗的对这两个内建函数讲解一下:

hasattr(act,animal) ----> 该语句的意思是:将输入的字符串与实例中的方法进行匹配,如果匹配上就返回True,匹配不上就返回False。

getattr(act,animal) ----> 该语句的意思是:将输入的字符串与实例中的方法进行匹配,如果匹配上就返回方法的内存地址,匹配不上就会有报错,见下图:

复制代码
#!/usr/bin/env python
# -*- coding=utf-8 -*-

class Action(object):
    def dog(self):
        print("汪汪汪")
    def cat(self):
        print("喵喵喵")

if __name__ == "__main__":
    animal = raw_input("Please write you want the animals:")
    act = Action()
    # if hasattr(act,animal):
    func = getattr(act,animal)
    # func()
    # else:
    #     print("You write the animal is not existed !")

执行结果如下:
"D:\Program Files (x86)\Python27\python.exe" F:/Python/Alex/s12/Blog/reflect.py
Please write you want the animals:tiger
Traceback (most recent call last):
  File "F:/Python/Alex/s12/Blog/reflect.py", line 14, in <module>
    func = getattr(act,animal)
AttributeError: 'Action' object has no attribute 'tiger'
复制代码

因此在使用getattr()是可以结合hasattr()或者在方法名确定情况下进行调用!
除了getatta()和hasattr()外,还有setattr()和delattr()。

下面通过例子来全面了解这四个内建函数:

复制代码
>>> class myClass(object):
...     def __init__(self):
...         self.foo = 100
... myInst = myClass()
>>> hasattr(myInst,'foo')
True
>>> getattr(myInst,'foo')
100
>>> hasattr(myInst,'bar')
False
>>> getattr(myInst,'bar')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: 'myClass' object has no attribute 'bar'
>>> setattr(myInst,'bar','my attr')
>>> dir(myInst)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo']
>>> getattr(myInst,'bar')
'my attr'
>>> delattr(myInst,'foo')
>>> dir(myInst)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar']
>>> hasattr(myInst,'foo')
False
复制代码

二、总结:
hasattr()函数是布朗型的,它的目的就是为了决定一个对象是否有一个特定的属性,一般用于访问某属性前先做一下检查。getattr()和setattr()函数相应地取得和赋值给对象的属性,getattr()会在你试图读取一个不存在的属性时,引发AttributeError异常,除非给出那个可选的默认参数。setattr()将要么加入一个新的属性,要么取代一个已存在的属性。而delattr()函数会从一个对象中删除属性。

三、全面解析:

复制代码
#!/usr/bin/env python
# -*- coding=utf-8 -*-

class Action(object):
    def __init__(self,country,zoo):
        self.country = country
        self.zoo = zoo
    def dog(self):
        print("汪汪汪")
    def cat(self):
        print("喵喵喵")

def animal_place(ins,name):
    print("the animal's place is ",name,ins.country)


if __name__ == "__main__":
    animal = raw_input("Please write you want the animals:")
    act = Action('USA','zoo')
    if hasattr(act,animal):
        func = getattr(act,animal)   #获取act.dog内存地址
        func()   #act.dong()
    else:
        print("You write the animal is not existed !")
        #想要让函数animal_place能跟实例act中方法一样执行
    setattr(act,'run',animal_place)
    act.run(act,'cat')
        #删除类Action中cat方法
    act.cat()
    delattr(Action,'cat')
    act.cat()
    #删除实例act中country的属性
    print(act.country)
    delattr(act,'country')
    print(act.country)

执行结果如下:
"D:\Program Files (x86)\Python27\python.exe" F:/Python/Alex/s12/Blog/reflect.py
Please write you want the animals:dog
汪汪汪
("the animal's place is ", 'cat', 'USA')
喵喵喵
Traceback (most recent call last):
  File "F:/Python/Alex/s12/Blog/reflect.py", line 31, in <module>
    act.cat()
AttributeError: 'Action' object has no attribute 'cat'


USA
Traceback (most recent call last):
  File "F:/Python/Alex/s12/Blog/reflect.py", line 35, in <module>
    print(act.country)
AttributeError: 'Action' object has no attribute 'country'
复制代码
分享到:
评论

相关推荐

    Python-Python实现反射式SO注入技术

    了解了Python反射式SO注入的基本原理后,我们可以看到`SnakeEater-master`这个压缩包可能是一个包含示例代码或者工具的项目,用于演示或研究如何实现和防范这种攻击。通过深入研究该项目的源代码,我们可以更深入地...

    简单谈谈python的反射机制

    下面结合一个web路由的实例来阐述python的反射机制的使用场景和核心本质。 一、前言 def f1(): print("f1是这个函数的名字!") s = "f1" print("%s是个字符串" % s)  在上面的代码中,我们必须区分两个概念,f1...

    python树莓派红外反射传感器

    ### Python树莓派红外反射传感器知识点详解 #### 一、引言 在现代电子技术领域,传感器的应用极为广泛,尤其在机器人技术、自动化控制、智能家居等领域发挥着重要作用。红外反射传感器作为常见的一种传感器类型,...

    python3 反射的四种基本方法解析

    这四个基本方法——getattr()、hasattr()、setattr() 和 delattr(),构成了Python反射的核心,使得代码更加灵活和动态。下面我们将逐一详细介绍这些方法。 1. getattr() 方法 getattr() 方法用于获取对象的属性或...

    python类似java的反射操作

    在Python编程语言中,虽然没有像Java那样直接的“反射”机制,但Python提供了一套类似的动态类型系统和元编程能力,使得程序在运行时能够检查、修改甚至创建类和对象。这种特性使得Python代码更加灵活,允许程序员在...

    Python关于反射和类的特殊成员方法

    Python关于反射和类的特殊成员方法

    学习python第十一天 反射、动态加载模块.pdf

    Python反射机制和动态加载模块 Python语言中有一个非常重要的功能称为反射机制(Reflection),它允许程序在运行时访问、检测和修改自身的状态或行为,这种能力也被称为自省(Introspection)。在Python中,反射...

    yagrc:另一个(Python)gRPC反射客户端

    用于Python的极简反射客户端。 可以通过在其proto文件中定义的名称来获取反射的grpc类型类,或者通过导入与使用protoc时相同的模块来使用。 因为有时候,必须运行协议可能会带来不便。 先决条件 要使用此项目中的...

    python入门教程(非常详细),从零基础入门到精通,看完这一篇就够了.pdf

    * Python 之数据类型之可变与不可变类型 * Python 之深浅 copy * Python 小数据池、代码块的深入剖析 * 拓展:Python 格式化字符串的 4 种方式 第六章:数据类型的内置方法 * Python 之数字类型内置方法 * Python ...

    python中反射用法实例

    在Python编程语言中,反射(Reflection)是一种强大的特性,它允许在运行时动态地访问和修改对象的属性、方法和模块。具体来说,反射机制通过内置的函数如type()、getattr()、setattr()和hasattr()来操作对象的内部...

    Python反射用法实例简析

    本文实例讲述了Python反射用法。分享给大家供大家参考,具体如下: class Person: def __init__(self): self.name = "zjgtan" def getName(self): return self.name 反射的简单含义: 通过类名获得类的实例...

    python(反射)_.pptx

    - 反射,reflection,指的是运行时获取类型定义信息。 一个对象能够在运行时,像照镜子一样,反射出其类型信息。

    Python中反射和描述器总结

    在Python中,能够通过一个对象,找出type、class、attribute或者method的能力,成为反射。 函数与方法 内建函数: getattr(object,name[,degault]) 通过name返回object的属性值,当属性不存在,将使用default返回,...

    Python3.6简单反射操作示例

    Python的反射机制是一种动态类型特性,它允许程序在运行时检查和修改自身的结构。在Python中,这通常通过内置函数如`getattr()`、`hasattr()`和`setattr()`来实现。下面将详细解释这些概念、原理以及如何在Python3.6...

    Python反射的用法实例分析

    为了实现这种需求,Python提供了一种机制,叫做反射(Reflection)。反射让我们能在运行时检查、调用或修改对象的属性和方法。本文将详细介绍Python中反射的几个常用方法,并通过实例演示如何使用这些方法。 首先,...

    python(反射)_.mp4

    - 反射,reflection,指的是运行时获取类型定义信息。 一个对象能够在运行时,像照镜子一样,反射出其类型信息。

    Python源码剖析(含目录+Small Python源码)

    8. **元编程**:介绍元类、装饰器和反射等高级技术,帮助读者掌握自定义Python行为的方法。 9. **并发与并行**:讲解Python的线程、进程和异步编程模型,如GIL(全局解释器锁)的影响和解决策略。 10. **扩展...

    Python反射和内置方法重写操作详解

    本文实例讲述了Python反射和内置方法重写操作。分享给大家供大家参考,具体如下: isinstance和issubclass isinstance(obj,cls)检查是否obj是否是类 cls 的对象,类似 type() class Foo(object): pass obj = Foo()...

Global site tag (gtag.js) - Google Analytics