面向对象之:元类,反射, 双下方法
程序员文章站
2022-03-20 22:06:16
[TOC] 1.元类 python 中一切皆对象, 类在某种意义上也是一个对象,python中自己定义的类,以及大部分内置类,都是由type元类(构建类)实例化得来的 2.反射 实例对象 类 本模块 其他模块 hasattr getattr setattr delattr 2.1实例对象: 2.2从 ......
目录
1.元类
class a: pass obj = a() print(type('abc')) # <class 'str'> print(type([1,2,3])) # <class 'list'> print(type((22,33))) # <class 'tuple'> # type 获取对象从属于的类 print(type(a)) # <class 'type'> print(type(str)) # <class 'type'> print(type(dict)) # <class 'type'>
python 中一切皆对象, 类在某种意义上也是一个对象,python中自己定义的类,以及大部分内置类,都是由type元类(构建类)实例化得来的
# type 与 object 的关系. # print(type(object)) object类是type类的一个实例. # object类是type类的父类. print(issubclass(type,object))
2.反射
实例对象 类 本模块 其他模块
hasattr getattr setattr delattr
2.1实例对象:
class a: country = '中国' def __init__(self,name,age): self.name = name self.age = age def func(self): print('in a func') obj = a('赵海狗',47) # hasattr print(hasattr(obj,'name')) print(hasattr(obj,'country')) print(hasattr(obj,'func')) # getattr print(getattr(obj,'name')) print(getattr(obj,'func')) f = getattr(obj,'func') f() print(getattr(obj,'sex',none)) if hasattr(obj,'name'): getattr(obj,'name') # setattr,delattr # 用的很少 obj.sex = '公' print(obj.sex) setattr(obj,'sex','公') print(obj.__dict__) delattr(obj,'name') print(obj.__dict__)
2.2从类的角度:
class a: country = '中国' def __init__(self,name,age): self.name = name self.age = age def func(self): print(self) print('in a func') # if hasattr(a,'country'): # print(getattr(a,'country')) if hasattr(a,'func'): obj = a('赵海狗', 26) getattr(obj,'func')() getattr(a,'func')(obj)
2.3从其他模块:
import tbjx print(getattr(tbjx,'name')) getattr(tbjx,'func')() # 1. 找到tbjx对象 的c类,实例化一个对象. print(getattr(tbjx,'c')) obj = getattr(tbjx,'c')('123') # 2. 找到tbjx对象 的c类,通过对c类这个对象使用反射取到area. print(getattr(tbjx.c,'area')) # 3. 找到tbjx对象 的c类,实例化一个对象,对对象进行反射取值. obj = getattr(tbjx,'c')('赵海狗') print(obj.name) print(getattr(obj,'name')) # 从当前模块研究反射: a = 666 def func1(): print('in 本模块这个对象') def func1(): print('in func1') def func2(): print('in func2') def func3(): print('in func3') def func4(): print('in func4') import sys # print(sys.modules[__name__]) # print(getattr(sys.modules[__name__],'a')) # getattr(sys.modules[__name__],'func1')() # getattr(sys.modules[__name__],'func2')() # getattr(sys.modules[__name__],'func3')() func_lst = [f'func{i}' for i in range(1,5)] print(func_lst) for func in func_lst: getattr(sys.modules[__name__],func)()
class user: user_list = [('login','登录'),('register','注册'),('save', '存储')] def login(self): print('欢迎来到登录页面') def register(self): print('欢迎来到注册页面') def save(self): print('欢迎来到存储页面') while 1: choose = input('请输入序号: \n1: 登录\n2: 注册\n3: 存储\n').strip() # 1 obj = user() getattr(obj, obj.user_list[int(choose)-1][0])() # getattr(obj,'login')
3.函数与方法的区别
def func1(): pass class a: def func(self): pass # 1. 通过打印函数名的方式区别什么是方法,什么是函数. (了解) print(func1) print(a.func) # 通过类名调用的类中的实例方法叫做函数. obj = a() print(obj.func) # 通过对象调用的类中的实例方法叫方法. # 2. 可以借助模块判断是方法还是函数. from types import functiontype from types import methodtype def func(): pass class a: def func(self): pass obj = a() print(isinstance(func,functiontype)) # true print(isinstance(a.func,functiontype)) # true print(isinstance(obj.func,functiontype)) # false print(isinstance(obj.func,methodtype)) # true # 总结: # python 中一切皆对象, 类在某种意义上也是一个对象,python中自己定义的类, # 以及大部分内置类,都是由type元类(构建类)实例化得来的. # python 中一切皆对象, 函数在某种意义上也是一个对象,函数这个对象是从functiontype这个类实例化出来的. # python 中一切皆对象, 方法在某种意义上也是一个对象,方法这个对象是从methodtype这个类实例化出来的.
class a: @classmethod def func(cls,a): pass @staticmethod def func1(): pass # a.func(222) # a.func() # obj = a() # obj.func() # 总结: 如何判断类中的是方法还是函数. # 函数都是显性传参,方法都是隐性传参.
4.特殊双下方法
特殊的双下方法: 原本是开发python这个语言的程序员用的.源码中使用的.
str : 我们不能轻易使用.慎用.
双下方法: 你不知道你干了什么就触发某个双下方法.
4.1__len__
class b: def __init__(self,name,age): self.name = name self.age =age def __len__(self): print(self.__dict__) return len(self.__dict__) # 2 b = b('leye',28) print(len(b)) # dict print(len({'name': 'leye', 'age': 28}))
4.2__len__
class a(object): pass obj = a() print(hash(obj)) print(hash('fdsaf'))
4.3__str__
class a: def __init__(self,name,age): self.name = name self.age =age def __str__(self): print(666) return f'姓名: {self.name} 年龄: {self.age}' a = a('赵海狗',35) b = a('李业',56) c = a('华丽',18) # 打印对象触发__str__方法 print(f'{a.name} {a.age}') print(f'{b.name} {b.age}') print(f'{c.name} {c.age}') print(a) print(b) print(c) # 直接str转化也可以触发. print(str(a))
4.4__repr__
print('我叫%s' % ('alex')) print('我叫%r' % ('alex')) print(repr('fdsaf')) class a: def __init__(self,name,age): self.name = name self.age =age def __repr__(self): print(666) return f'姓名: {self.name} 年龄: {self.age}' a = a('赵海狗',35) b = a('李业',56) c = a('华丽',18) # print(a) print(repr(a))
4.5__call__
__call__方法 *** 对象() 自动触发对象从属于类(父类)的__call__方法 class foo: def __init__(self): pass def __call__(self, *args, **kwargs): print('__call__') obj = foo() obj()
4.6__eq__
class a(object): 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 return true x = a() y = a() print(x == y) x = 1 y = 2 print(x+y)
4.7__del__
__del__析构方法 class a: def __del__(self): print(666) obj = a() del obj
4.8__new__
# __new__ *** new一个对象 构造方法 class a(object): def __init__(self): self.x = 1 print('in init function') def __new__(cls, *args, **kwargs): print('in new function') return object.__new__(a) # object 342534 # 对象是object类的__new__方法 产生了一个对象. a = a() # 类名() # 1. 先触发 object的__new__方法,此方法在内存中开辟一个对象空间. # 2. 执行__init__方法,给对象封装属性. print(a) # python中的设计模式: 单例模式 # 一个类只允许实例化一个对象. class a: pass obj = a() print(obj) obj1 = a() print(obj1) obj2 = a() print(obj2) # 手写单例模式 class a: __instance = none def __init__(self,name): self.name = name def __new__(cls,*args,**kwargs): if not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instance obj = a('alex') print(obj) obj1 = a('李业') print(obj1.name) print(obj.name)