zoukankan      html  css  js  c++  java
  • Python 反射机制

    Python的反射机制

      Python的反射机制,就是反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!

      常用的反射内置函数有四个:hasattr(),getattr(),setattr()和delattr()。我们来看看具体应该怎么使用。

    首先定义一个类并实例化,再定义个字符串变量从键盘输入。

     1 def cry(self):
     2     print("%s is crying!"%self.name)
     3 class Person(object):
     4     def __init__(self,name):
     5         self.name = name
     6     def eat(self):
     7         print("%s is eating "%(self.name))
     8     def talk(self):
     9         print(("%s is talking"%self.name))
    10 p1 = Person("Jack")
    11 action = input(">>>:")

    要想用输入的字符串来调用实例中的属性或功能,用p1.action是不行的

    >>>:eat
    Traceback (most recent call last):
      File "D:/python/week7/反射.py", line 14, in <module>
        p1.action
    AttributeError: 'Person' object has no attribute 'action'
    运行结论

    最简单暴力的方法有一种:

    class Person(object):
        def __init__(self,name):
            self.name = name
        def eat(self):
            print("%s is eating "%(self.name))
        def talk(self):
            print(("%s is talking"%self.name))
    p1 = Person("Jack")
    action = input(">>>:")
    if action == 'eat':
        p1.eat()
    elif action == 'talk':
        p1.talk()

    可是如果类里定义了上百中功能,靠if来比较输入字符串显然是不靠谱的,也太low了。这时候,就用上反射了。

     1 class Person(object):
     2     def __init__(self,name):
     3         self.name = name
     4     def eat(self):
     5         print("%s is eating "%(self.name))
     6     def talk(self):
     7         print(("%s is talking"%self.name))
     8 p1 = Person("Jack")
     9 action = input(">>>:")
    10 if hasattr(p1,action):          #hasattr(obj,func_str):判定实例内是否有名字为str的功能或属性
    11     print(getattr(p1,action))   #gatattr(obj,func_str):返回实例内名字为str的功能的地址或属性的值  
                         如果action = name,运行结果为Jack,如果action=eat,则返回值为eat()在内存中的地址

    通过hasattr()函数来判定实例内是否包含输入名字和字符串一致的属性或功能,返回值为Ture 或False 就可以和if等指令配合使用。

    注意getattr()的返回值,如果输入字符串的是属性名字,则返回值为属性的值,而输入的是功能的名字,返回值就是地址,换句话说在地址后加(),并在括号内加上实参,就能运行函数。

     1 class Person(object):
     2     def __init__(self,name):
     3         self.name = name
     4     def eat(self,food):   #这里加了个形参
     5         print("%s is eating %s"%(self.name,food))
     6     def talk(self):
     7         print(("%s is talking"%self.name))
     8 p1 = Person("Jack")
     9 action = input(">>>:")
    10 if hasattr(p1,action):
    11     done = getattr(p1,action)
    12     done("cake")        #在这里给形参food传递实参
    >>>:eat
    Jack is eating cake
    运行结果

    setattr()用来对实例的属性或功能进行更改或添加。

     1 def cry(self):          #定义了一个类里没有的函数
     2     print("%s is crying!"%self.name)
     3 class Person(object):
     4     def __init__(self,name):
     5         self.name = name
     6     def eat(self,food):
     7         print("%s is eating %s"%(self.name,food))
     8     def talk(self):
     9         print(("%s is talking"%self.name))
    10 p1 = Person("Jack")
    11 action = input(">>>:")
    12 if hasattr(p1,action):
    13     pass
    14 else:
    15     setattr(p1,action,cry)      #setattr(obj,a,b)把名为b的功能添加在obj中,新功能/属性名为a
    16     done = getattr(p1,action)
    17     done(p1)                    #这里比把p1作为实参传递给新添加的功能
    >>>:cry
    Jack is crying!
    运行结果

    在上例中输入字符串为“cry”,实例中没有,就通过setattr()增加新的功能。然后用getattr()调用新添加的功能,这里一定要把实例作为实参传给新添加的功能(因为定义的cry需要调用实例里的属性)

    setattr()还可用作更改实例的属性,如果属性内不含输入的字符串,则增加新的属性。

    1 setattr(p1,action,"Lucy")
    2 print(p1.name)    #在输入name后,p1的name就编程Lucy了。

    最后,delattr()用来删除实例中的属性或功能具体用法就是delattr(obj,str)删除boj内名为str的功能或属性。

  • 相关阅读:
    @ModelAttribute注解详细使用
    Spring MVC使用注解实现账户注册与登陆
    @PathVariable、@RequestHeader与@CookieValue注解的使用案例
    IDEA搭建我的第一个Spring MVC应用(附使用注解实现)
    JDBC自定义工具类
    JDBC与MySQL实现分页查询技术
    JavaWeb实战——记录网站上一次访问时间
    微信小程序使用setData修改数组中的指定下标的属性值
    Centos6.x 无法 ping 外网 --- 已解决
    Ckeditor失去焦点前保留光标位置
  • 原文地址:https://www.cnblogs.com/yinsedeyinse/p/10035718.html
Copyright © 2011-2022 走看看