内置方法
Python的Class机制内置了很多特殊的方法来帮助使用者高度定制自己的类,这些内置方法都是以双下划线开头和结尾的,会在满足某种条件时自动触发
__str__
含义
__str__方法会在对象被打印(print)操作的时候,自动触发,该方法必须返回字符串类型的数据。很多时候用来更加精准的描述对象
使用
class MyClass(object):def __init__(self, name):self.name = namedef __str__(self):"""该方法必须返回字符串类型的数据"""return "对象:%s" % self.nameobj = MyClass('kevin')# print(obj) # (没有__str__)# <__main__.MyClass object at 0x7fd2bb457860>print(obj)# 对象:kevinprint(MyClass)# <class '__main__.MyClass'>
__del__
含义
__del__方法会在对象被执行(被动、主动)删除操作之后自动执行。
Python的垃圾回收机制会自动清理Python程序的资源,当一个对象只占用应用程序级资源时,完全没必要为对象定制__del__方法,但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下,关于系统资源的回收,Python的垃圾回收机制便派不上用场了,需要我们为对象定制该方法,用来在对象被删除时自动触发回收系统资源的操作
使用
被动删除
class MyClass(object):def __init__(self, name):self.name = namedef __del__(self):"""对象被执行删除操作之后执行(垃圾回收机制)"""print("__del__什么时候执行")obj = MyClass('kevin')print("被动删除")# 被动删除# __del__什么时候执行
主动删除
class MyClass(object):def __init__(self, name):self.name = namedef __del__(self):"""对象被执行删除操作之后执行"""print("__del__什么时候执行")obj = MyClass('kevin')"""主动删除"""del obj# __del__什么时候执行print("主动删除")# 主动删除
__getattr__
含义
__getattr__方法会在对象查找不存在的“名字”时候自动触发
使用
class MyClass(object):def __init__(self, name):self.name = namedef __getattr__(self, item):"""对象查找不存在名字的时候自动触发"""return "不好意思,没有%s这个名字" % item # item 表示不存在的"名字",类型是字符串obj = MyClass('kevin')print(obj.name)# kevinprint(obj.age)# 不好意思,没有age这个名字
__setattr__
含义
__setattr__方法在对象添加属性操作的时候自动触发
使用
class MyClass(object):def __init__(self, name):self.name = namedef __setattr__(self, key, value):"""对象在执行添加属性操作的时候自动触发>>>obj.变量名=变量值"""print("__setattr__方法")print(key, value)obj = MyClass('kevin')# __setattr__方法# name kevinprint(obj.__dict__) # 因为重写了__setattr__,赋值操作都会触发它的运行,根本没赋值,除非直接接操作属性字典,否则永远无法赋值# {}obj.age = 22# __setattr__方法# age 22print(obj.__dict__) # 因为重写了__setattr__,赋值操作都会触发它的运行,根本没赋值,除非直接接操作属性字典,否则永远无法赋值obj.__dict__['name'] = 'tony'print(obj.__dict__)# {'name': 'tony'}
__call__
含义
__call__方法在对象被加括号调用的时候自动触发,使实例的对象能够像函数一样被调用
使用
class MyClass(object):def __init__(self, name):self.name = namedef __call__(self, *args, **kwargs):"""在对象被加括号的时候自动触发"""print("__call__方法", args, kwargs)obj = MyClass('kevin')obj()# __call__方法 () {}
__enter__、__exit__
含义
__enter__方法在对象被执行with上下文管理语法开始自动触发 ,该方法返回什么as后面的变量名就会得到什么
__exit__方法在对象被执行with上下文管理语法结束之后自动触发
使用
class MyClass(object):def __init__(self, name):self.name = namedef __enter__(self):print("__enter__方法")def __exit__(self, exc_type, exc_val, exc_tb):print("__enter__方法")obj = MyClass('kevin')with obj as f:print("开始前触发")print("结算后触发")# __enter__方法# 开始前触发# __enter__方法# 结算后触发
__getattribute__
含义
只要对象查找名字无论名字是否存在都会执行该方法,如果类中有__getattribute__方法那么就不会去执行__getattr__方法
使用
class MyClass(object):def __init__(self, name):self.name = namedef __getattr__(self, item):print(print("__getattr__方法", item))def __getattribute__(self, item):print("__getattribute__方法")return "这个名字是%s" % itemobj = MyClass('kevin')print(obj.name)# __getattribute__方法 name# 这个名字是name
__new__
含义
__new__用于产生空对象(并不是所有的地方都可以直接调用__new__ 该方法过于底层)
真正的构造函数是new
使用
# 在元类__new__里面,可以直接调用class Meta(type):def __new__(cls, *args, **kwargs):obj = type.__new__(cls, *args, **kwargs)return obj# 如果是在元类的__call__里面 需要间接调用class Mate(type):def __call__(self, *args, **kwargs):obj = object.__new__(self) # 创建一个空对象self.__init__(obj, *args, **kwargs) # 让对象去初始化return obj
笔试题
笔试题一
让字典具备句点符查找值的功能,
# 定义一个类继承字典class MyDict(dict):def __getattr__(self, item):return self.get(item)def __setattr__(self, key, value):self[key] = value'''要区别是名称空间的名字还是数据k:v键值对'''obj = MyDict({'name': 'kevin', 'age': 22})# 1.具备句点符取vprint(obj.name)# kevin# 2.具备句点符设k:vobj.gender = 'male'print(obj)# {'name': 'kevin', 'age': 22, 'gender': 'male'}
笔试题二
补全下列代码 使其运行不报错
"""class Context:passwith Context() as ctx:ctx.do_something()"""class Context:def __enter__(self):return selfdef __exit__(self, exc_type, exc_val, exc_tb):passdef do_something(self):passwith Context() as ctx:ctx.do_something()
