• python面向对象基础(二)反射


    1.反射

    前言

    如何动态输入一个模块名,可以随时访问到导入模块中的方法或者变量?

    in= input(“请输入你想导入的模块名:”)
    CC = __import__(in) 
        #這种方式就是通过输入字符串导入你所想导入的模块 
    CC.f1()  # 执行模块中的f1方法

    实现了动态输入模块名,从而使我们能够输入模块名并且执行里面的函数。但是执行的函数被固定了。如何实现动态输入函数名来执行呢?

    in = input("请输入模块:")
    mod= __import__(in)    # 等价于import in
    
    in_func = input("请输入要执行的函数:")
    f = getattr(mod,in_func,None)
    
    #作用:从导入模块中找到你需要调用的函数in_func,然后返回一个该函数的引用.没有找到就返回None
    
    f() # 执行该函数

    what

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。

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

    反射的四大金刚hasattr,getattr,setattr,delattr

    #是否有
    def
    hasattr(*args, **kwargs): # real signature unknown """ Return whether the object has an attribute with the given name. This is done by calling getattr(obj, name) and catching AttributeError. """ pass #得到 def getattr(object, name, default=None): # known special case of getattr """ getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case. """ pass
    #设置 def setattr(x, y, v): # real signature unknown; restored from __doc__ """ Sets the named attribute on the given object to the specified value. setattr(x, 'y', v) is equivalent to ``x.y = v'' """ pass #删除 def delattr(x, y): # real signature unknown; restored from __doc__ """ Deletes the named attribute from the given object. delattr(x, 'y') is equivalent to ``del x.y'' """ pass

     案例:

    对对象属性进行反射

    class A:
        f = '类的静态变量'
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def say_hi(self):
            print('hi,%s'%self.name)
    
    obj=A('斌哥',24)
    
    #检测是否含有某属性
    print(hasattr(obj,'name'))
    print(hasattr(obj,'say_hi'))
    
    #获取属性
    n=getattr(obj,'name')
    print(n)
    func=getattr(obj,'say_hi')
    # func2=getattr(obj,'say_hello')#没有该属性报错
    # AttributeError: 'Foo' object has no attribute 'say_hello'
    func3=getattr(obj,'say_hello',None)             #返回None
    func4=getattr(obj,'say_hello',"没有该属性")   #返回 "没有该属性"
    func()
    
    #设置属性
    #可以添加新属性,也可以更改旧属性
    setattr(obj,'还能长高',True)
    setattr(obj,'show_name',lambda self:self.name+'18cm')
    print(obj.__dict__)
    #{'还能长高': True, 'name': '斌哥', 'show_name': <function <lambda> at 0x0000024D6E9116A8>, 'age': 24}
    print(obj.show_name(obj)) #斌哥18cm
    
    # #删除属性
    delattr(obj,'age')
    delattr(obj,'show_name')
    # delattr(obj,'show_name111')#不存在,则报错
    
    #显示全部属性
    print(obj.__dict__)
    # {'还能长高': True, 'name': '斌哥'}

    对类属性 静态成员 类成员的反射

    class A(object):
     
        staticField = "毕业于南昌大学"
     
        def __init__(self):
            self.name = '王庆斌'
     
        def func(self):
            return '返回func方法'
     
        @staticmethod
        def func2():
            return '返回func2方法'
        @classmethod
        def func3(cls):
            return '返回func3方法'
     
    print(getattr(A, 'staticField'))
    print(getattr(A, 'func'))
    print(getattr(A, 'func2'))
    print(getattr(A,'func3'))
    
    
    setattr(A,'staticField','想毕业于五道口')
    print(A.staticField)


    毕业于南昌大学
    <function A.func at 0x0000024D6E9AC158>
    <function A.func2 at 0x0000024D6E9AC378>
    <bound method A.func3 of <class '__main__.A'>>

    想毕业于五道口

    #类方法一样的修改
    setattr(A,'func3',lambda:print("学会mongo"))
    A.func3() 

    学会mongo

     导入其他模块,利用反射查找该模块是否存在某个方法

    import sys
    
    
    def s1():
        print('s1')
    
    
    def s2():
        print('s2')
    
    
    this_module = sys.modules[__name__]
    
    hasattr(this_module, 's1') #true
    getattr(this_module, 's2') ==》得到该属性

    # test1.py
    class A:
        def func(self):
            return "func in A in 模块1"
    #test2.py
    import 模块1.test1 as test1
    
    print(hasattr(test1,"A"))
    a=test1.A()
    print(hasattr(a,'func'))
    a.func()
    
    Out:
    True
    True
    'func in A in 模块1'
  • 相关阅读:
    千万别用树套树 【题意:有多少线段完全覆盖某一线段【树状数组维护】】【模板题】
    Codeforces Round #590 (Div. 3)【D题:26棵树状数组维护字符出现次数】
    Codeforces Round #590 (Div. 3)【D题:维护26棵树状数组【好题】】
    Codeforces Round #350 (Div. 2) A B C D1 D2 水题【D2 【二分+枚举】好题】
    AtCoder Beginner Contest 142【D题】【判断素数的模板+求一个数的因子的模板】
    AtCoder Beginner Contest 116 D
    序列自动机【模板】
    题解 CF1428G Lucky Numbers (Easy Version and Hard Version)
    题解 CF1428F Fruit Sequences
    题解 P5401 [CTS2019]珍珠
  • 原文地址:https://www.cnblogs.com/wqbin/p/10381863.html
Copyright © 2020-2023  润新知