zoukankan      html  css  js  c++  java
  • 面向对象的反射和双下方法

    1.函数vs方法

    • 函数:全部都是显性传参

    • 方法:存在隐性传参

    • 判断方法

      • 通过函数名可大致判断

      • 通过types模块去验证

      • from types import FunctionType
        from types import MethodType
        
        
        def func():
            pass
        
        
        class A:
        
            def func(self):
                pass
        
            @staticmethod
            def f():
                pass
        # print(isinstance(func, FunctionType))
        # print(isinstance(func, MethodType))
        
        # 类名调用func 就是一个函数
        # print(isinstance(A.func, FunctionType))
        # print(isinstance(A.func, MethodType))
        # obj = A()
        # 对象调用func 就是一个方法
        # print(isinstance(obj.func, FunctionType))
        # print(isinstance(obj.func, MethodType))
        
        # 对于静态方法的研究
        # print(isinstance(A.f, FunctionType))
        # print(isinstance(A.f, MethodType))
        
        # obj = A()
        # # 对象调用func
        # print(isinstance(obj.f, FunctionType))
        # print(isinstance(obj.f, MethodType))
        

    2.反射

    • 概念:主要是指程序员可以访问,检测和修改它本身状态或行为的一种能力(自省),

    • python中面向对象的反射 : 通过字符串的形式操作对象的相关属性,python中的一切事物都是对象(都可以使用反射)

      • ['从实例的角度去研究反射']

      • # class A:
        #
        #     static_field = '静态属性'
        #
        #     def __init__(self,name,age):
        #         self.name = name
        #         self.age = age
        #
        #     def func(self):
        #         print('in A func')
        # obj = A('MC骚Q',18)
        # print(obj.name)
        
        # print(hasattr(obj,'name'))  #检查是否有'name'属性
        # print(getattr(obj,'name1','没有该属性')) #获取属性,如果没有设置第三个元素,查询不到就会报错
        # print(getattr(obj,'name'))
        # print(getattr(obj,'name1')) #报错
        #
        # setattr(obj,'hobby','玩')  #增加新的属性
        # print(getattr(obj,'hobby'))
        #
        # delattr(obj,'name')         #删除该属性
        # print(hasattr(obj,'name'))
        
        
        # if hasattr(obj,'static_field'):
        #     print(getattr(obj,'static_field'))
        #
        # if hasattr(obj,'func'):
        #     getattr(obj,'func')()#不用实例化,可直接调用方法
        
      • 从类的角度研究反射

      • # class A:
        #
        #     static_field = '静态属性'
        #
        #     def __init__(self,name,age):
        #         self.name = name
        #         self.age = age
        #
        #     def func(self):
        #         print('in A func')
        # obj = A('大表哥',18)
        # print(getattr(A,'func'))
        # getattr(A,'func')(obj)
        
      • 从脚本的角度研究反射

      • # import sys
        # def func1():
        #     print('in func1')
        # this_modules = sys.modules[__name__]  #获取当前脚本这个对象
        # print(this_modules)
        # print(getattr(this_modules,'func1'))
        # getattr(this_modules,'func1')()
        
        # class B:
        #     static = "B类"
        # import sys
        # this_modules = sys.modules[__name__]
        # cls = getattr(this_modules,"B")
        # obj = cls()
        # print(obj.static)
        
      • 应用场景

      • '选择界面'      
        # class Auth:
        #
        #     def login(self):
        #         print('登陆函数')
        #
        #     def register(self):
        #         print('注册函数')
        #
        #     def exit(self):
        #         print("退出")
        #
        # while 1:
        #     function_list = [('login','登录'),('register','注册'),("exit",'退出')]
        #     for num,option in enumerate(function_list,1):
        #         print(num,option[1])
        #     func_name = input("群输入选择:").strip()
        #     obj = Auth()
        #     if hasattr(obj,func_name):
        #         getattr(obj,func_name)()
        #     else:
        #         print('输入错误')
        

    3.双下方法

    • 双下方法是特殊方法,主要供python源码程序员使用

    • __len__

      • # class A:
        #     def __init__(self,name):
        #         self.name =name
        #
        #     def __len__(self):
        #         print('触发__len__方法')
        #         return 10
        #
        # obj = A('MC')
        # ret = len(obj)
        # print(ret)
        
    • __hash__

      • class A:
            def __init__(self):
                self.a = 1
                self.b = 2
        
            def __hash__(self):
                return hash(str(self.a)+str(self.b))
        a = A()
        print(hash(a))
        
    • __str__

      • # class A:
        #
        #     def __init__(self):
        #         self.name = '太白'
        #
        #     def __str__(self):
        #         return self.name
        #
        # obj = A()
        # print(obj)
        # print(str(obj))
        
    • __repr__

      • # class Student:
        #     def __init__(self,name,age,sex):
        #         self.name = name
        #         self.age =age
        #         self.sex = sex
        #
        #     def __repr__(self):
        #         return "12"
        #
        #     def __str__(self):
        #         return f"{self.sex}123"
        #
        # object = Student(1,2,3)
        # object1 = Student(1,2,4)
        # object2 = Student(1,2,5)
        #
        # print(str(object))  #会触发__str__
        # print(object)
        # print(object1)
        # print(object2)
        # print(f"此对象为%s" %object) #格式化输出会触发__str__
        # print(f"此对象为%r" %object) #格式化输出会触发__repr__
        #
        # print(obj) #同时存在__str__和__repr__会优先选择__str__执行,优先级别高
        
    • __call__

      • # class A:
        #     def __init__(self):
        #         self.a =1
        #         print(111)
        #
        #     def __call__(self, *args, **kwargs):
        #         print(666)
        #
        # obj = A()
        # obj()
        
    • __eq__

      • class A:
            def __init__(self):
                self.a = 1
                self.b = 2
        
            def __eq__(self,obj):
                if  self.a == obj.a and self.b == obj.b:
                    return True
        a = A()
        b = A()
        print(a == b)
        
    • __del__

      • 析构方法,当对象在内存中被释放时,自动触发执行
      • 此方法一般无需定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因此此工作都是交给python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发和执行的.
    • __new__

      • # class A(object):
        #
        #     def __init__(self):
        #         print('in __init__')
        #
        #     def __new__(cls, *args, **kwargs):
        #         print(cls) #A
        #         print('in __new__')
        #         object1 = object.__new__(cls)  #2. 其次利用object类的__new__产生一个对象空间
        #         return object  # #3. 将这个对象空间返回给了A()即obj
        #
        # obj = A()#1. 先触发__new__,将类名自动传给cls
        
    • __item__

      • class Foo:
            def __init__(self,name):
                self.name=name
        
            def __getitem__(self, item):
                print(self.__dict__[item])
        
            def __setitem__(self, key, value):
                self.__dict__[key]=value
            def __delitem__(self, key):
                print('del obj[key]时,我执行')
                self.__dict__.pop(key)
            def __delattr__(self, item):
                print('del obj.key时,我执行')
                self.__dict__.pop(item)
        
        f1=Foo('sb')
        f1['age']=18
        f1['age1']=19
        del f1.age1
        del f1['age']
        f1['name']='alex'
        print(f1.__dict__)
        
    • 上下文管理器相关__enter__和__exit__

      • # 如果想要对一个类的对象进行with  as 的操作 不行。
        class A:
            def __init__(self, text):
                self.text = text
        
        with A('大爷') as f1:
            print(f1.text)
        
      • class A:
            
            def __init__(self, text):
                self.text = text
            
            def __enter__(self):  # 开启上下文管理器对象时触发此方法
                self.text = self.text + '您来啦'
                return self  # 将实例化的对象返回f1
            
            def __exit__(self, exc_type, exc_val, exc_tb):  # 执行完上下文管理器对象f1时触发此方法
                self.text = self.text + '这就走啦'
                
        with A('大爷') as f1:
            print(f1.text)
        print(f1.text)
        
      • 自定义上下文管理器

      • class Diycontextor:
            def __init__(self,name,mode):
                self.name = name
                self.mode = mode
         
            def __enter__(self):
                print "Hi enter here!!"
                self.filehander = open(self.name,self.mode)
                return self.filehander
         
            def __exit__(self,*para):
                print "Hi exit here"
                self.filehander.close()
         
         
        with Diycontextor('py_ana.py','r') as f:
            for i in f:
                print i
        
  • 相关阅读:
    Oracle 集合类型
    JAVA_SE_笔记整理(反射机制)
    JAVA_SE_笔记整理(GUI)
    JAVA_SE_笔记整理(网络编程)
    JAVA_SE_笔记整理(多线程)
    JAVA_SE_笔记整理(流)
    JAVA_SE_笔记整理(集合三)
    JAVA_SE_笔记整理(集合二)
    JAVA_SE_笔记整理(集合一)
    JAVA_SE_笔记整理(面向对象四(接口,包,内部类))
  • 原文地址:https://www.cnblogs.com/W-Y-C/p/11178071.html
Copyright © 2011-2022 走看看