Python面向对象
一、__init__和__new__的区别
__init__和__new__都是python类中的内置方法
new方法的参数是cls–当前类本身
init方法的参数是slef–实例化的对象
new方法:实例化对象(开辟内存空间)
init方法:对实例化对象进行初始化操作
new方法和init方法会在创建对象时自动被调用,new方法在init方法之前被调用
new方法实例化对象(创建一个内存空间),将实例化的对象return给init,init再对这个实例对象(内存空间)进行初始化属性,如果new方法没有return,init方法不会被调用
总结:
通过一个类创建对象时,会先自动调用new方法,开辟一个内存空间给实例化对象,然后return这个内存空间给init方法,init方法再对这个内存空间进行初始化操作
二、如何派生内置不可变类型并修改实例化行为
解决方案:实现__new__(),在其中修改实例化行为。
>>> class IntTuple(tuple):
def __new__(cls,iterable):
f_it = [e for e in iterable if isinstance(e,int) and e>0]
return super().__new__(cls,f_it)
>>> int_t=IntTuple([1,-1,'abc',6,['x','y'],3])
>>> print(int_t)
(1, 6, 3)
三、如何为创建大量实例节省内存
解决方案:定义类的__slots__属性,声明实例有哪些属性(关闭动态绑定 )
四、让对象支持上下文管理协议
实现了__enter__() 和__exit__()方法
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, exc_db):
内部过程
配合with语句使用的时候,上下文管理器会自动调用__enter__方法,然后进入运行时上下文环境,并将__enter__函数返回值赋值给as从句变量 f
当退出with语句块或者是出现异常导致程序退出时,会执行__exit__方法,并把异常信息传递给后面的参数exc_type, exc_value, exc_db
如果__exit__方法返回True,则with语句块不会显示的抛出异常,程序终止
如果__exit__方法返回None或者False,异常会被主动抛出,程序终止
五、如何创建可管理的对象属性
解决方案:
1.为类的属性设置set和get方法
2.使用property(fget,fset,fdel)函数为类创建可管理属性,fget,fset,fdel对应相应属性访问
六.让类支持比较操作
解决方案:
方案一:重载类的比较运算符函数
__lt__,__gt__,__le__,__ge__,__eq__
方案二:在类上使用functools.total_ordering装饰器,只需实现上述函数中的两个,即可实现全部的比较运算符重载
七、使用描述符对实例属性做类型检查
目的:希望像静态类型语言那样,对他们的实例属性做类型检查,可对实例属性指定类型,赋予不正确类型是抛出异常
方法:分别实现__get__,__set__,__delete__方法,在__set__内使用isinstance函数做类型检查