• day7面向对象--反射


    反射

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

        1、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.

        判断类中是否有指定的方法,如下:

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self):
            print("%s is eating......" %self.name)
    
    d = Dog("alex")
    choice = input(">>:").strip()    #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
    print(hasattr(d,choice))
    运行如下:
    >>:talk
    False
    >>:eat
    True

        我们知道,有时候我们要根据用户输入来判断类中是否有某种方法,这样我们就能执行了。如何去判断呢?可以使用hasattr(object,name)方法。上面,我们实现了动态判断方法,如果存在返回True,否则返回False。

        2、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.

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self):
            print("%s is eating......" %self.name)
    
    d = Dog("alex")
    choice = input(">>:").strip()    #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
    print(getattr(d,choice))
    运行结果如下:
    >>:tall
    Traceback (most recent call last):
      File "/home/zhuzhu/第七天/get_attr.py", line 11, in <module>
        print(getattr(d,choice))
    AttributeError: 'Dog' object has no attribute 'tall'
    >>:eat
    <bound method Dog.eat of <__main__.Dog object at 0x7fecf92428d0>>

        从上面可以看出,getattr()是获取属性的内存地址,如果存在返回内存地址,如果不存在,则返回错误,提示类中不存在这个方法。

        既然getattr()存在放回方法的内存地址,那么加上括号执行一下,如下:

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self):
            print("%s is eating......" %self.name)
    
    d = Dog("alex")
    choice = input(">>:").strip()    #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
    getattr(d,choice)()
    运行结果如下:
    >>:eat
    alex is eating......

        从上面可以看出,程序正常执行了,通过上面,我们可以发现,hasattr()和getattr()经常结合一起使用,hasattr()判断是否有这个方法,而getattr()用来执行。如果存在,则调用getattr()进行执行。如下:

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self):
            print("%s is eating......" %self.name)
    
    d = Dog("alex")
    choice = input(">>:").strip()    #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
    if hasattr(d,choice):
        '''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
        getattr(d,choice)()
    
    else:
        print("您输入的方法不存在,请核对后重新输入:")
    运行结果如下:
    >>:eat #存在执行方法
    alex is eating......
    >>:tall #不存在,提示方法没有
    您输入的方法不存在,请核对后重新输入

        从上面代码可以看出,能够实现动态用户输入判断方法是否存在,存在执行,不存在提示的功能。

        下面是实现带参数的情况:

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self,food):
            print("%s is eating......%s" %(self.name,food))
    
    d = Dog("alex")
    choice = input(">>:").strip()    #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
    if hasattr(d,choice):
        '''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
        func = getattr(d,choice)
        func("chenronghua")
        #getattr(d,choice)("chenronghua")
    
    else:
        print("您输入的方法不存在,请核对后重新输入:")
    运行结果如下:
    >>:eat
    alex is eating......chenronghua

       也可以判断属性是否存在,如下,就判断里面单纯的属性,得到属性值:

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self,food):
            print("%s is eating......%s" %(self.name,food))
    
    d = Dog("alex")
    choice = input(">>:").strip()    #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
    if hasattr(d,choice):
        '''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
        func = getattr(d,choice)
        print(func)
        # func("chenronghua")
        #getattr(d,choice)("chenronghua")
    
    else:
        print("您输入的方法不存在,请核对后重新输入:")
    运行结果如下:
    >>:name
    alex

        3.setattr(obj, name, value, /)
        Sets the named attribute on the given object to the specified value.
        
        setattr(x, 'y', v) is equivalent to ``x.y = v''
        添加动态属性:

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self,food):
            print("%s is eating......%s" %(self.name,food))
    
    def talk(self):
        print("%s is talking....." %self.name)
    
    def laugh(self):
        print("%s is laughing....." %self)
    
    d = Dog("alex")
    choice = input(">>:").strip()    #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
    if hasattr(d,choice):
        '''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
        func = getattr(d,choice)
        print(func)
        # func("chenronghua")
        #getattr(d,choice)("chenronghua")
    
    else:
        #setattr(d,choice,laugh)     #动态添加一个属性
        setattr(d,"alex","sb")      #动态加入一个属性
        print(getattr(d,"alex"))
    运行结果如下:
    >>:alex
    sb

        添加动态方法:

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self,food):
            print("%s is eating......%s" %(self.name,food))
    
    def talk(name):
        print("%s is talking....." %name)
    
    def laugh(self):
        print("%s is laughing....." %self)
    
    d = Dog("alex")
    choice = input(">>:").strip()    #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
    if hasattr(d,choice):
        '''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
        func = getattr(d,choice)
        print(func)
        # func("chenronghua")
        #getattr(d,choice)("chenronghua")
    
    else:
        setattr(d,choice,laugh)     #动态添加一个属性
        #setattr(d,"alex","sb")      #动态加入一个属性
        print(getattr(d,choice)("alex"))

        其实,setattr(obj,name_str,属性/方法)就是把一个属性/方法赋值给name_str,如果第三参数是一个方法,那么就赋值了一个方法给name_str,如果第三参数是一个属性,那么就赋值一个属性给name_str,是属性,使用getattr(obj,name_str)得到的是一个字符串;是方法,使用get(obj,name_str)得到的是一个方法的内存地址,其实本质还是上面的getattr(),方法就要看是否有参数,有参数就加入参数调用执行,没有参数就直接加括号执行。

        4.delattr(obj, name, /)
        Deletes the named attribute from the given object.
        
        delattr(x, 'y') is equivalent to ``del x.y''

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self,food):
            print("%s is eating......%s" %(self.name,food))
    
    def talk(name):
        print("%s is talking....." %name)
    
    def laugh(self):
        print("%s is laughing....." %self)
    
    d = Dog("alex")
    choice = input(">>:").strip()    #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
    if hasattr(d,choice):
        '''这种场景在很多情况下都使用,比如让用户输入某个功能,如果存在执行,不存在则告诉用户没有这个功能'''
        func = getattr(d,choice)
        print(func)
        # func("chenronghua")
        #getattr(d,choice)("chenronghua")
    
    else:
        setattr(d,choice,laugh)     #动态添加一个属性
        #setattr(d,"alex","sb")      #动态加入一个属性
        getattr(d,choice)("alex")
        delattr(d,choice)            #删除属性或者方法
        getattr(d, choice)("alex")

        delattr(obj,name_str)删除实例中的方法或者属性。

        反射:

            hasattr(obj,attr),判断一个对象里是否有对应的字符串的方法

            getattr(obj,name_str),根据字符串去获取obj对象里对应的方法的内存地址。

            setattr(obj,name_str,z)等价于obj.name_str = z

            delattr(obj,name_str)删除实例汇总的方法或属性

    class Dog(object):
    
        def __init__(self,name):
            self.name = name
    
        def eat(self,food):
            print("%s is eating......%s" %(self.name,food))
    
    def talk(name):
        print("%s is talking....." %name)
    
    def laugh(self):
        print("%s is laughing....." %self)
    
    d = Dog("alex")
    choice = input(">>:").strip()    #用户输入函数,判断函数是否存在,存在执行,反射来判断执行
    set_what = input("把那个变量赋值给属性:").strip()
    
    if hasattr(d,choice):
        getattr(d,choice)
    else:
        setattr(d,choice,laugh)
        v = getattr(d,choice)
        if type(v) == str:
            print(v)
        else:
            print(v("alex"))
    运行结果如下:
    >>:alex
    把那个变量赋值给属性:sb
    alex is laughing.....
    None

        上面实例是对setattr()的进一步补充,其实就是设置属性或者方法。

  • 相关阅读:
    012 数据类型基础
    013 数据类型:数字类型
    Codeforces 235C Cyclical Quest (后缀自动机)
    BZOJ 4032 Luogu P4112 [HEOI2015]最短不公共子串 (DP、后缀自动机)
    BZOJ 4278 [ONTAK2015]Tasowanie (后缀数组)
    [加强版] Codeforces 835D Palindromic characteristics (回文自动机、DP)
    BZOJ 4044 Luogu P4762 [CERC2014]Virus Synthesis (回文自动机、DP)
    BZOJ 2434 Luogu P2414 [NOI2011]阿狸的打字机 (AC自动机、树状数组)
    BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)
    BZOJ 4327 [JSOI2012]玄武密码 (AC自动机)
  • 原文地址:https://www.cnblogs.com/gengcx/p/7258299.html
Copyright © 2020-2023  润新知