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

    通过字符串映射或修改程序运行时的状态、属性、方法, 可以通过下面这4中方法

      ''' 
       使用getattr(object, name_str, default=None) 方法获取object对象里
       对应的方法或者属性的内存地址
       如果是属性:直接返回属性值
       如果是方法:返回方法的内存地址     
       '''
    getattr(object, name, default=None)
    # hasattr(object,name_str) 判断object对象是否有一个名为name_str的方法或者属性
    hasattr(object,name_str)

    代码演示:

    # -*- coding:utf8 -*-
    class  Person(object):
        def __init__(self, name):
            self.name = name
    
        def fun(self):
            print("%s正在玩耍" % self.name)
    
    p1 = Person("某人飞")
    
    name_str = input("请输入方法或者属性").strip()
    # hasattr(object,name_str) 判断object对象是否有一个名为name_str的方法或者属性
    if hasattr(p1, name_str):
       ''' 
       如果有就可以使用getattr(object, name_str, default=None) 方法获取object对象里
       对应的方法或者属性的内存地址
       如果是属性:直接返回属性值
       如果是方法:返回方法的内存地址     
       '''
       print(getattr(p1, name_str , 80))
       # >>>name: 某人飞
       # >>>fun : <bound method Person.fun of <__main__.Person object at 0x0000020B76A81370>>
       # 所以如果是方法,那么可以这么处理
       a = getattr(p1, name_str)
       a()
    else:
        print("该对象没有这些属性和方法")
    判断和获取的演示

    如果对象没有从键盘录入的该方法,那么可以使用,setattr添加一个方法

    def bulk(self):
        print("这是在%s对象的类外部创建的方法"%self.name)
    
    
    class  Person(object):
        def __init__(self, name):
            self.name = name
    
        def fun1(self):
            print("%s正在玩耍" % self.name)
    
    p1 = Person("某人飞")
    name_str = input("请输入您的方法或者属性").strip()
    if hasattr(p1, name_str):
        a = getattr(p1, name_str)
        a()
    else:  #如果没有这个方法,那么为其创建一个已经存在的方法
        """
        setattr(p1, name_str, bulk)
        为对象p1添加一个已经存在的bulk的方法,命名为name_str
        """
        setattr(p1, name_str, bulk)
        a = getattr(p1, name_str)
        a(p1)
    """
    运行结果
    请输入您的方法或者属性ui
    这是在某人飞对象的类外部创建的方法
    """
    setattr(p1, name_str, bulk)添加方法

    如果对象没有从键盘录入的该方法,那么可以使用,setattr添加一个属性

    class  Person(object):
        def __init__(self, name):
            self.name = name
    
    p1 = Person("某人飞")
    name_str = input("请输入您的方法或者属性").strip()
    if hasattr(p1, name_str):
        a = getattr(p1, name_str)
        print(a)
        # 也可以同setattr修该已有属性的值
        setattr(p1, name_str, "")
        print(p1.name)
    else:  #如果没有这个属性,那么为其添加一个属性 ,并为其设置一个默认值20
        setattr(p1, name_str, 20)
        a = getattr(p1, name_str)
        print(a)
    """
    运行结果:
    请输入您的方法或者属性name
    某人飞
    飞
    
    运行结果:
    请输入您的方法或者属性age
    20
    """
    setattr(p1, name_str, index)添加属性

    删除对象中的属性和方法(其中方法并不能删除

    class  Person(object):
        def __init__(self, name):
            self.name = name
    
        def fun(self):
            print("这是一个实例方法")
    
    p1 = Person("某人飞")
    name_str = input("请输入您的方法或者属性").strip()
    if hasattr(p1, name_str):
        # 删除这个对象的属性或者方法
        delattr(p1, name_str)
    else:
        pass
    
    print(p1.name)
    p1.fun()
    """
    运行结果:
    请输入您的方法或者属性name
    AttributeError: 'Person' object has no attribute 'name'
    
    运行结果:
    请输入您的方法或者属性fun
    AttributeError: fun
    """
    delattr(p1, name_str)只能删除属性,和动态添加的方法

    注意:通过delattr能够删除通过setattr动态添加的方法,其实也是一个假象。真相是通过setattr添加的一个方法并不是真的给这个对象添加了一个方法,而是添加了一个属性,setattr方法的第二个参数就是这个属性的名字,然后这个属性的值是一个指向外部函数的引用地址,所以当我们调用这个对象的属性时,实际上是间接调用了这个函数,看起来就像是这个对象添加了一个方法一样,但本质上仍然是添加的一个属性。不管是setattr和delattr,其实都只能针对对象的属性进行操作,它们对对象的方法是无法直接操作的。

  • 相关阅读:
    在Cortex-M系列上如何准确地做us级延时?
    [嵌入式开发]Linux性能分析——上下文切换
    cnless.sh:改进版less,可自动识别GBK编码或UTF-8编码。
    PuTTY配置
    LINUX内核笔记:自旋锁
    Vue的父子组件间通信及借助$emit和$on解除父子级通信的耦合度高的问题
    elementUi中input输入字符光标在输入一个字符后,光标失去焦点
    elementUi中的计数器ele-mumber中的change事件传参及事件调用
    如何使用git拉取代码及提交代码(详细)
    git 拉取远程代码
  • 原文地址:https://www.cnblogs.com/fjfsu/p/15575227.html
Copyright © 2011-2022 走看看