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__)
 
 
 


 
 
原文地址:https://www.cnblogs.com/echo2019/p/10289972.html