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

    反射

    • 通过字符串映射或修改程序运行时的状态,属性,方法.
    • 有以下四种方法:
      • getattr(object, name, default = None)
      • hasattr(object, name)
      • setattr(x,y,v)
      • delattr(x,y)
      • #!/usr/bin/python
        # -*- coding: utf-8 -*-
        
        
        def bulk(self):
            print("%s is yelling...." % self.name)
        
        
        class Dog(object):
            def __init__(self, name):
                self.name = name
        
            def eat(self, food):
                print("%s is eating %s...", self.name, food)
        
            def walk(self):
                print("%s is walking...", self.name)
        
        
        d = Dog("NHY")
        choice = input(">>:").strip()   # 用户输入"吃", 就调用eat()方法; 用户输入"走", 就调用walk()方法
        
        # print(hasattr(d, choice))  # 判断用户输入是否存在于实例d中. 若用户输入eat, 会返回True;  若用户输入talk,会返回False.
        
        """
        但是即使eat返回True,也不能直接调用 d.choice, 因为choice是不存在的, 必须把用户输入的eat调出来, 需要用到getattr()方法
        """
        # print(getattr(d, choice))  # 若用户输入eat, 就返回一个内存地址(返回内存地址之后, 加括号就能调用相应方法了); 若用户输入talk,因为不存在, 会返回False.
        
        # getattr(d, choice)("包子")  # 若用户输入eat,此行代码相当于调用 eat()方法. 若不需要传参数, 直接getattr(d, choice)()即可.
        
        """
        反射步骤总结: 
          1. hasattr(obj, name_str) 判断是否存在某字符串的方法映射
          2. getattr(obj, name_str) 若该映射存在, 获取该映射对应方法的内存地址
          3a. getattr(obj, name_str)() 如果是一个方法, 获取内存地址之后, 调用相关方法
          3b. setattr(ojb, 'y', v) 如果是一个属性, 重新设置该属性的值. is equivalent to obj.y = v.
          4. delattr() 删除一个属性
        """
        
        # 传递一个动态方法
        if hasattr(d, choice):
            # getattr(d, choice)()  # 这样直接调用eat()方法, 有时还需要传参数,可以用下面的方法
            func = getattr(d, choice)
            func("馒头")
        else:
            setattr(d, choice, bulk)  # 传递一个动态方法. 即不存在的映射, 可以添加. 但是前提相关方法必须已经存在.
            setattr(d, choice, None)  # 传递一个动态属性
        
        d.talk(d)  # 用户输入talk, 所以要调用talk(),而不是bulk(). bulk相当于一个变量名, 此处因用户输入了talk,用talk来代替. 相当于d.talk = bulk, 所以d.talk()就是调用bulk()方法.
        
        """
        上面写死了. 因为不确定用户choice会输入什么, 所以应该用一个变量来接收getattr()的值
        """
        if hasattr(d, choice):
            # getattr(d, choice)()  # 这样直接调用eat()方法, 有时还需要传参数,可以用下面的方法
            func = getattr(d, choice)
            func("馒头")
        else:
            setattr(d, choice, bulk)  # 传递一个动态方法. 即不存在的映射, 可以添加. 但是前提相关方法必须已经存在.
            setattr(d, choice, None)  # 传递一个动态属性
            func = getattr(d, choice)
            func(d)  # 这样不论用户choice输入的是什么都可以直接调用func(d)来执行了.不用写死成d.talk().
        
        
        
        # 传递一个动态属性, 或给已有属性重新赋值
        if hasattr(d, choice):
            attr = getattr(d, choice)
            setattr(d, choice, "RGH")  # 更改已有属性值. 在choice里填name, 改的就是name的值.
        else:
             setattr(d, choice, None)  # 传递一个动态属性. None是这个动态属性的默认值.可以是None,也可以是其它值,如2233等.
             # setattr(d, choice, 22)
             print(getattr(d, choice))
        
        print(d.name)
        
        
        # 删除一个属性
        if hasattr(d, choice):
            delattr(d, choice)
  • 相关阅读:
    InPut 标签 HTML(表单)
    JavaScript Table 对象
    JCBD
    JCBD
    JavaScript prototype 属性
    Java8 新特性
    JavaScript 对象的使用
    Java 反射
    虚拟机VirtualBox启动虚拟机报Only Ethernet Adapter' (VERR_INTNET_FLT_IF_NOT_FOUND).
    Impala 数值函数
  • 原文地址:https://www.cnblogs.com/cheese320/p/9227340.html
Copyright © 2011-2022 走看看