zoukankan      html  css  js  c++  java
  • 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)Python27python.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)Python27python.exe" F:/Python/Alex/s12/Blog/reflect.py
    Please write you want the animals:cat
    喵喵喵
    
    "D:Program Files (x86)Python27python.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)Python27python.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)Python27python.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'
  • 相关阅读:
    微信二维码 场景二维码 用于推送事件,关注等 注册用户 ,经过测试
    简单的 Helper 封装 -- CookieHelper
    简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)
    Java反射机制
    Windows Azure Web Site (13) Azure Web Site备份
    Windows Azure Virtual Machine (1) IaaS用户手册
    Windows Azure Web Site (1) 用户手册
    Windows Azure Web Site (12) Azure Web Site配置文件
    Windows Azure Web Site (11) 使用源代码管理器管理Azure Web Site
    Windows Azure Web Site (10) Web Site测试环境
  • 原文地址:https://www.cnblogs.com/Richardzhu/p/5297119.html
Copyright © 2011-2022 走看看