python学习之老男孩python全栈第九期_day027知识点总结——反射、类的内置方法
一. 反射
''' # isinstance class A:pass class B(A):pass a = A() print(isinstance(a,A)) # 判断对象和类的关系 print(issubclass(B,A)) # 判断子类和父类的关系 print(issubclass(A,B)) ''' #--------------------------------------------------------------------------------# # # 反射:是用字符串类型的名字,去操作变量 # # hasattr # # getattr # # setattr # # delattr # name = 1 # eval('print(name)') # 安全隐患 # # # 反射 就没有安全问题 # # # 反射对象中的属性和方法 # class A: # def func(self): # print('in func') # a = A() # a.name = 'alex' # a.age = 63 # # 反射对象的属性 # ret = getattr(a,'name') # 通过变量名的字符串形式取到的值 # print(ret) # # # 变量名 = input('>>>') # func # # print(getattr(a,变量名)) # # print(a.__dict__[变量名]) # # # 反射对象的方法 # getattr(a,'func')() #--------------------------------------------------------------------------------# ''' 反射类的属性 class A: price = 20 def func(self): print('in func') # A.price print(getattr(A,'price')) ''' #--------------------------------------------------------------------------------# ''' # 反射类的方法:classmethod staticmethod class A: price = 20 @classmethod def func(cls): print('in func') # A.func() if hasattr(A,'func'): # 如果能找到则执行下面的语句 getattr(A,'func')() ''' #--------------------------------------------------------------------------------# # 模块 # 反射模块的属性 # import monday # # print(monday.day) # monday # print(getattr(monday,'day')) # # 反射模块的方法 # getattr(monday,'wahaha')() # 内置模块也能用 #----------------------------------------------------------------------------------# ''' year = 2018 import sys # print(sys.modules['__main__'].year) # 2018 # 反射自己模块中的变量 def qqxing(): print('qqxing') print(getattr(sys.modules['__main__'], 'year')) # 反射自己模块中的函数 # getattr(sys.modules['__main__'], 'qqxing')() 变量名 = input(">>>") print(getattr(sys.modules[__name__],变量名)) ''' # import time # x = input('>>>') # print(getattr(time,x)()) # 一个模块中的类能不能反射得到? 能 # import monday # getattr(monday,'C') # # if hasattr(monday,'year'): # getattr(monday,'year') ''' # setattr 设置一个变量 class A: pass a = A() setattr(a,'name','nezha') # 给a设置一个name为nezha setattr(A,'name','alex') # 给A添加一个name为alex print(a.name) print(A.name) # delattr 修改一个变量 delattr(a,'name') # 删除的是对象a的name print(a.name) # 对象a中找不到name,去A类中找到了 delattr(A,'name') print(a.name) # 报错 '''
二. 类的内置方法
# 内置的类方法,和内置的函数之间有着千丝万缕的联系 # 双下方法 # obj.__str__ # print(str(1)) # # # obj.__repr__ # print(1,'1') # print(repr(1)) # print(repr('1')) # # class A: # pass # a = A() # print(str(a)) # 现在a 里面找str,没找到 就找父类object的str方法 # <__main__.A object at 0x000001F60CEF0E48> # # object 里有一个 __str__ ,一旦被调用,就返回调用这个方法的对象的内存地址 # # class B: # def __str__(self): # return "B's object" # def func(self): # return 'wahaha' # b = B() # print(b) # 打印一个对象的时候,就是调用 b.__str__ # print(str(b)) # # # l = [1, 2, 3, 4, 5] # 实例化了一个列表类的对象 # # print(l) # # print('%s:%s'%('B',b)) # %s str() 直接打印 实际上都是走的__str__ # class Teacher: # def __init__(self, name, salary): # self.name = name # self.salary = salary # def __str__(self): # return "Teacher's object:%s"%self.name # def func(self): # return "wahah" # alex = Teacher('alex',250) # print(alex) # __repr__ # # class Teacher: # def __init__(self, name, salary): # self.name = name # self.salary = salary # def __repr__(self): # return str(self.__dict__) # def func(self): # return "wahah" # # alex = Teacher('alex',250) # # print(repr(alex)) # %r repr() 实际上都是走的 __repr__ # # print('>>>%r'%alex) # # print(str(alex)) # 没有打印内存地址 # print('>>>%s'%alex) # repr 是 str 的备胎...反过来不可以(也就是str 不是 repr 的备胎) # print()/%s/str(obj)的时候,实际上是内部调用了obj.__str__方法,如果有str方法,那么他返回的必定是一个 字符串(必须是字符串,不能是数字等.) # 如果没有__str__方法,会先找本类中的__repr__方法,在没有,再找父类中的__str__方法,若父类没有,就找__repr__...一直找到object中的__str__ # repr() 只会找__repr__ ,如果没有,就找父类的 # 所以 若 repr 和str只能实现一个方法的话 ,应该实现repr方法,因为str也可以用repr # 内置的方法有很多,不一定都在object中 # class A: # pass # # def __len__(self): # # return 10 # a = A() # print(len(a)) # object of type 'A' has no len() #-------------------------------------------------------------------------# # class Classes: # def __init__(self, name): # self.name = name # self.student = [] # def __len__(self): # return len(self.student) # # py_s9 = Classes('python全栈9期') # py_s9.student.append('二哥') # py_s9.student.append('哥') # py_s9.student.append('二') # print(len(py_s9)) # ----------------------------------------------------------------------------------- # # __del__ # # class A: # def __del__(self): # 析构函数:在删除一个对象之前进行一些收尾工作 # self.f.close() # a = A() # a.f = open() # 打开文件 ,第一 在操作系统中打开了一个文件 拿到了文件操作符存在了内存中 # del a # a.f 拿到了文件操作符消失在了内存中 # # import time # time.sleep(3) # # del a # del 先执行了这个方法,然后再删除这个变量 # # # 引用计数 # # print(a) # -------------------------------------------------------------------------------------------------------------------- # # __call__ class A: def __init__(self, name): self.name = name def __call__(self): ''' 打印这个对象中的所有属性 :return: ''' for k in self.__dict__: print(k,self.__dict__[k]) # a = A('alex')() # # a = A('alex') # a() # 一个对象 加上括号 相当于执行__call__方法