python面向对象之反射

发布时间:2019-06-28 17:40:52编辑:auto阅读(1089)

    一、静态方法(staticmethod)和类方法(classmethod)


    类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属×××互(也就是可以使用类属性)

    静态方法:让类里的方法直接被类调用,就像正常调用函数一样


    类方法和静态方法的相同点:都可以直接被类调用,不需要实例化

    类方法和静态方法的不同点:

      类方法必须有一个cls参数表示这个类,可以使用类属性

      静态方法不需要参数


    绑定方法:分为普通方法和类方法

         普通方法:默认有一个self对象传进来,并且只能被对象调用-------绑定到对象

          类方法:默认有一个cls对象传进来,并且可以被类和对象(不推荐)调用-----绑定到类


    非绑定方法:静态方法:没有设置默认参数,并且可以被类和对象(不推荐)调用-----非绑定


    import time
    class Date:
        def __init__(self,year,month,day):
            self.year=year
            self.month=month
            self.day=day
        # @staticmethod
        # def now():
        #     t=time.localtime()
        #     return Date(t.tm_year,t.tm_mon,t.tm_mday)
        @classmethod         #改成类方法
        def now(cls):
            t=time.localtime()
            return cls(t.tm_year,t.tm_mon,t.tm_mday) #哪个类来调用,即用哪个类cls来实例化
    class EuroDate(Date):
        def __str__(self):
            return 'year:%s month:%s day:%s' %(self.year,self.month,self.day)
    e=EuroDate.now()
    print(e)               #我们想触发EuroDate.__str__,此时e就是由EuroDate产生的,结果如我们所愿
    '''
    输出结果:
    year:2017 month:3 day:3
    '''

    二、反射

    反射:可以用字符串的方式去访问对象的属性,调用对象的方法(但是不能去访问方法),python中一切皆对象,都可以使用反射。


    反射有四种方法:

    hasattr:hasattr(object,name)判断一个对象是否有name属性或者name方法。有就返回True,没有就返回False

    getattr:获取对象的属性或者方法,如果存在则打印出来。hasattr和getattr配套使用

        需要注意的是,如果返回的是对象的方法,返回出来的是对象的内存地址,如果需要运行这个方法,可以在后面添加一对()

    setattr:给对象的属性赋值,若属性不存在,先创建后赋值

    delattr:删除该对象指定的一个属性


    1、对象应用反射

    class Foo:
        def __init__(self):
            self.name = 'egon'
            self.age = 51
        def func(self):
            print('hello')
    egg = Foo()
    
    print(hasattr(egg,'name'))      #先判断name在egg里面存在不存在,结果是True
    print(getattr(egg,'name'))      #如果为True它才去得到,结果是egon
    print(hasattr(egg,'func'))     #结果是True
    print(getattr(egg,'func'))     #得到的是地址<bound method Foo.func of <__main__.Foo object at 0x0000000001DDA2E8>>
    getattr(egg,'func')()        #在这里加括号才能得到,因为func是方法,结果是hello
    
    一般用法如下,先判断是否hasattr,然后取getattr
    if hasattr(egg,'func'):
        getattr(egg,'func')()   #结果是hello
    else:
        print('没找到')

    2、类应用反射

    class Foo:
        f = 123
        @classmethod
        def class_method_dome(cls):
            print('class_method_dome')
        @staticmethod
        def static_method_dome():
            print('static_method_dome')
            
    print(hasattr(Foo,'class_method_dome'))         #结果是True
    method = getattr(Foo,'class_method_dome')
    method()                               #结果是class_method_dome
    
    print(hasattr(Foo,'static_method_dome'))         #结果是True
    method1 = getattr(Foo,'static_method_dome')
    method1()                              #结果是static_method_dome

    3、模块应用反射

    # 1.导入其他模块引用

    import mymodule
    print(hasattr(mymodule,'test'))
    getattr(mymodule,'test')()
    
    
    p = getattr(mymodule,'test')
    p()                              #相当于上面getattr(mymodule,'test')()

    # 2.在本模块中应用反射

    def demo1():
        print('hello')
    import sys
    module_obj = sys.modules[__name__]        #相当于'__main__'
    print(module_obj)                 #结果是<module '__main__' from 'C:/Users/Administrator/Desktop/test.py'>
    print(hasattr(module_obj,'demo1'))       #结果是True
    getattr(module_obj,'demo1')()          #结果是hello

    导入自己的模块的例子:

    def 注册():
        print('regiester')
    def 登录():
        print('login')
    def 购物():
        pass
    print('注册,登录,购物')
    ret = input('请输入你要做的操作:')
    import sys
    my_module = sys.modules[__name__]  #利用sys模块导入一个自己的模块
    if hasattr(my_module,ret):
        getattr(my_module,ret)()



关键字