zoukankan      html  css  js  c++  java
  • day 22 反射,双下方法

    反射:

    反射:通过字符串去操作对象(类,空间等等)的属性或方法
    反射的四个方法
      hasattr ***
      getattr  ***  
      setattr  ***  
      delattr  ***
    # getattr 用法
    class
    A: role = '太白' def func(self): print(666) conter = input('请输入: ') #str类型 输入role ret = getattr(A,conter) # 即使conter = 'role'字符串的role,A.role也可以找到 print(ret)

    hasattr, getattr, setattr, delattr  用法示例

    # 操作对象的角度
    class
    A: country = 'China' area = '深圳' def __init__(self,name,age): self.name = name self.age = age def func(self): print(666) # obj = A('忠敏',18) # print(obj.name) # 忠敏 print(hasattr(obj,'name')) # True 判断对象有没有此属性 if hasattr(obj,'name'): print(getattr(obj,'name')) # 相当于 print(obj.name) print(getattr(obj,'sex',None)) # 获得obj的sex值,如果没有则返回None print(obj.country) print(getattr(obj,'country')) # 可以获得类的静态属性 obj.func() ret = getattr(obj, 'func') # ret = func的内存地址 print(ret) ret() print(obj.sex) # 没有改属性,报错 setattr(obj,'sex','') # 设置sex = '男' print(obj.sex) delattr(obj,'name') # 删除该属性 print(obj.name)

    操作类的角度

    class A:
        country = 'China'
        area = '深圳'
    
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def func(self):
            print(666)
    
    print(getattr(A,'country'))  #
    print(getattr(A,'area'))
    print(getattr(A,'name))    # name是对象的属性,类找不到
    getattr(A,'func')(23)   # 可以执行类的方法
    print(hasattr(A,'func2'))  # False   没有func2

    操作另一个py文件

    import attr   # attr.py
    print(getattr(attr,'flag'))
    # 1,找到func 并执行
    ret = getattr(attr,'func')
    print(ret(10))
    #2,找到B类并调用 name_list func函数
    b = getattr(attr,'B')
    print(b.name_list)

    本文件操作

    import sys
    obj = sys.modules[__name__]  # obj = 本py文件
    print(obj)
    # def func():
    #     print(666)
    #
    # ret = input('>>>')  # 输入func
    # # ret() # 无法执行func()
    # getattr(obj,ret)()  # 可以执行func()
    
    def func1():
        print('in func1')
    
    def func2():
        print('in func2')
    
    def func3():
        print('in func3')
    
    l1 = ['func%s' % i for i in range(1,4)]  # l1 = ['func1', 'func2', 'func3']
    print(l1)
    # print(l1)
    for i in l1:   #  i = 'func1'  字符串
        getattr(obj,i)()   
    到底什么对象才可以用反射?
    实例化对象 类 其他模块 本模块 只有能通过.的方式获取的,才可以用反射。(函数不能使用反射)

    双下方法:(含有两个下划线

    双下方法是给python源码的开发者用

    s1 = 'saekfjldkjase'
    print(len(s1))   # 相当于  s1.__len__()
    print(s1.__len__())
    isinstance 判断此对象是不是该类(或者是该类的子类)实例化的对象
    class A: pass
    class B(A): pass
    obj = A()
    print(isinstance(obj,A))  #  True
    print(isinstance(obj,B))  #  False
    issubclass 判断的是此类是不是后面类的派生类
    
    
    class D: pass
    class A(D): pass
    class B(A): pass
    print(issubclass(B,A)) #True
    print(issubclass(B,D)) #True
    特殊双下方法:
    # __len__ 方法
    
    class A:
        def __init__(self,name,age):
            self.name = name
            self.age = age
            self.sex = ''
    
        def __len__(self):
            # print(666)
            return len(self.__dict__)  # 返回字典的长度
    a = A('barry', 18)
    len(a)   # len(对象) 如果此类中有__len__ 方法会自动执行__len__
    print(len(a))

    __hash__     __str__

    class A:
        def __init__(self,name,age):
            self.name = name
            self.age = age
            self.sex = ''
    
        def __len__(self):
            # print(666)
            return len(self.__dict__)
    
        def __hash__(self):
            return 1
    
        def __str__(self):
            print(555)
            return 'fdsaf'
    
    # object
    a = A('barry', 18)
    print(hash(a))   # 定义了__hash__方法,所以自动执行
    print(a,type(a))  # 对一个对象打印时,自动触发类中的__str__方法

    __call__ 方法: 对象(),会触发 __call__ 方法

    class Foo:
    
        def __init__(self):
            print(11)
    
        def __call__(self, *args, **kwargs):
            print(123)
    
    obj = Foo()
    obj()  # 对象() 触发 __call__方法
    __new__ 方法,实例化对象发生的三件事
    1, 类名() 执行object.__new__方法,开辟对象空间并返回
    2,自动执行__init__方法,将空间创给self
    3,在__init__给对象封装属性
    class A:
        def __init__(self,name):
            self.name = name
            print('in A __init__')
        def __new__(cls, *args, **kwargs):  # 自定义了一个__new__方法
            print('in A __new__')
            return object.__new__(cls)     # 返回一个python内置的__new__方法
    
    a = A('春哥')
    print(a.name)
    单例模式: 让一个类只能实例化一个对象
    class A():
        __instance = None
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def __new__(cls, *args, **kwargs):
            if cls.__instance is None:
                obj = object.__new__(cls)
                cls.__instance = obj
            return cls.__instance
    item系列将对象视为字典使用时,就会触发item方法
    class Foo:
        def __init__(self,name):
            self.name = name
    
        def __getitem__(self, item):
            # print(666)
            return self.name
            # print(self.__dict__[item])
    
        def __setitem__(self, key, value):
            # print(key)
            # print(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')
    ret = f1['name']
    print(ret)
    # f1['age'] = 12
    # # print(f1.__dict__)
    # print(f1.age)
    #
    #
    # f1['age']=18
    # f1['age1']=19
    # del f1.age1
    # del f1['age']
    # f1['name']='alex'
    # print(f1.__dict__)
     
     
     


     
     
  • 相关阅读:
    创建Django项目
    CVE-2011-0104:Microsoft Office Excel 栈溢出漏洞修复分析
    HDU 1089 到1096 a+b的输入输出练习
    ocrosoft 程序设计提高期末复习问题M 递归求猴子吃桃
    HDU 1406 完数
    ocrosoft 1015 习题1.22 求一元二次方程a*x^2 + b*x + c = 0的根
    php-amqplib库操作RabbitMQ
    rabbitmq 使用PhpAmqpLib
    RabbitMQ的持久化
    Rabbitmq各方法的作用详解
  • 原文地址:https://www.cnblogs.com/echo2019/p/10289972.html
Copyright © 2011-2022 走看看