反射:
通过字符串去操作对象(类,空间等等)的属性或方法
四个方法:
hasattr(object,"name") *** (判断一个对象里面是否有name属性或者方法,返回BOOL值,有name特性返回True, 否则返回False。
需要注意的是"name"要用字符串格式双引号包起来)
# 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(hasattr(obj,'name')) # True
getattr(object," name") *** (获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。
需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
可以在后面添加一对括号。)
# 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(hasattr(obj,'name')) # if hasattr(obj,'name'): #如果对象有返回True # print(getattr(obj,'name')) # print(getattr(obj,'sex',None)) 没有可以自定义返回值None # print(obj.country) # print(getattr(obj,'country')) # obj.func() # ret = getattr(obj,'func') 对象调用方法 # print(ret) # ret()
setattr(object,"name","values") * (给对象的属性赋值,若属性不存在,先创建再赋值。)
delattr(object,"name") * (把对象的属性或者方法删除)
# 到底什么对象才可以用反射?
# 实例化对象 类 其他模块 本模块 只有能通过.的方式获取的,才可以用反射。
# import sys # obj = sys.modules[__name__] # print(type(obj)) # # print(getattr(obj,'func')) # 为什么这里要通过本模块? 因为这些函数属于本模块的方法。
特殊的双下方法:
双下方法不是提供给你用的,他是给python源码的那些开发者用。
isinstance 判断此对象是不是该类(或者是该类的子类)实例化的对象
# class A: pass # class B(A): pass # # obj = B() # s1 = 'afds' # print(isinstance(obj,B)) #True # print(isinstance(obj,A)) #True # print(isinstance(s1,str)) #True
# issubclass 判断的是此类是不是后面类的派生类
# class D: pass # class A(D): pass # class B(A): pass # abj = B() # print(issubclass(B,A)) #True # print(issubclass(B,D)) #True
# __init__
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)) # print(hash('fsdaf')) # 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)) # print(a) # 对一个对象打印时,自动触发类中的__str__方法 # print(a,type(a))
# __call__
# class Foo: # # def __init__(self): # print(11) # # def __call__(self, *args, **kwargs): # pass # obj = Foo() # obj() # 对象() 触发 __call__方法
# __new__ 构造方法 ***
# class A: # def __init__(self,name): # self.name = name # print('in A __init__') # object # obj = A('alex') # object # class A: # def __init__(self,name): # self.name = name # print('in A __init__') # def __new__(cls, *args, **kwargs): # print('in A __new__') # return object.__new__(cls) # # a = A('春哥') # print(a.name) # 1, 类名() 执行object.__new__方法,开辟的对象空间并返回 # 2,自动执行__init__方法,将空间创给self # 3,在__init__给对象封装属性。
# 单例模式: 一个类只能实例化一个对象 ***(面试题)
# class A: # pass # ret1 = A() # ret2 = A() # ret3 = A() # print(ret1) # print(ret2) # print(ret3) # 实例化了三个对象空间地址 # 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 # ret1 = A('alex',123) # ret2 = A('wusir',22) # ret3 = A('barry',18) # print(ret1) # print(ret2) # print(ret3) # 就在内存空间创建了一个对象空间地址
# 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__) #