内置方法

PythonClass机制内置了很多特殊的方法来帮助使用者高度定制自己的类,这些内置方法都是以双下划线开头和结尾的,会在满足某种条件时自动触发

__str__

含义

__str__方法会在对象被打印(print)操作的时候,自动触发,该方法必须返回字符串类型的数据。很多时候用来更加精准的描述对象

使用

  1. class MyClass(object):
  2. def __init__(self, name):
  3. self.name = name
  4. def __str__(self):
  5. """该方法必须返回字符串类型的数据"""
  6. return "对象:%s" % self.name
  7. obj = MyClass('kevin')
  8. # print(obj) # (没有__str__)
  9. # <__main__.MyClass object at 0x7fd2bb457860>
  10. print(obj)
  11. # 对象:kevin
  12. print(MyClass)
  13. # <class '__main__.MyClass'>

__del__

含义

__del__方法会在对象被执行(被动、主动)删除操作之后自动执行。

Python的垃圾回收机制会自动清理Python程序的资源,当一个对象只占用应用程序级资源时,完全没必要为对象定制__del__方法,但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下,关于系统资源的回收,Python的垃圾回收机制便派不上用场了,需要我们为对象定制该方法,用来在对象被删除时自动触发回收系统资源的操作

使用

被动删除

  1. class MyClass(object):
  2. def __init__(self, name):
  3. self.name = name
  4. def __del__(self):
  5. """对象被执行删除操作之后执行(垃圾回收机制)"""
  6. print("__del__什么时候执行")
  7. obj = MyClass('kevin')
  8. print("被动删除")
  9. # 被动删除
  10. # __del__什么时候执行

主动删除

  1. class MyClass(object):
  2. def __init__(self, name):
  3. self.name = name
  4. def __del__(self):
  5. """对象被执行删除操作之后执行"""
  6. print("__del__什么时候执行")
  7. obj = MyClass('kevin')
  8. """主动删除"""
  9. del obj
  10. # __del__什么时候执行
  11. print("主动删除")
  12. # 主动删除

__getattr__

含义

__getattr__方法会在对象查找不存在的“名字”时候自动触发

使用

  1. class MyClass(object):
  2. def __init__(self, name):
  3. self.name = name
  4. def __getattr__(self, item):
  5. """对象查找不存在名字的时候自动触发"""
  6. return "不好意思,没有%s这个名字" % item # item 表示不存在的"名字",类型是字符串
  7. obj = MyClass('kevin')
  8. print(obj.name)
  9. # kevin
  10. print(obj.age)
  11. # 不好意思,没有age这个名字

__setattr__

含义

__setattr__方法在对象添加属性操作的时候自动触发

使用

  1. class MyClass(object):
  2. def __init__(self, name):
  3. self.name = name
  4. def __setattr__(self, key, value):
  5. """对象在执行添加属性操作的时候自动触发>>>obj.变量名=变量值"""
  6. print("__setattr__方法")
  7. print(key, value)
  8. obj = MyClass('kevin')
  9. # __setattr__方法
  10. # name kevin
  11. print(obj.__dict__) # 因为重写了__setattr__,赋值操作都会触发它的运行,根本没赋值,除非直接接操作属性字典,否则永远无法赋值
  12. # {}
  13. obj.age = 22
  14. # __setattr__方法
  15. # age 22
  16. print(obj.__dict__) # 因为重写了__setattr__,赋值操作都会触发它的运行,根本没赋值,除非直接接操作属性字典,否则永远无法赋值
  17. obj.__dict__['name'] = 'tony'
  18. print(obj.__dict__)
  19. # {'name': 'tony'}

__call__

含义

__call__方法在对象被加括号调用的时候自动触发,使实例的对象能够像函数一样被调用

使用

  1. class MyClass(object):
  2. def __init__(self, name):
  3. self.name = name
  4. def __call__(self, *args, **kwargs):
  5. """在对象被加括号的时候自动触发"""
  6. print("__call__方法", args, kwargs)
  7. obj = MyClass('kevin')
  8. obj()
  9. # __call__方法 () {}

__enter____exit__

含义

__enter__方法在对象被执行with上下文管理语法开始自动触发 ,该方法返回什么as后面的变量名就会得到什么

__exit__方法在对象被执行with上下文管理语法结束之后自动触发

使用

  1. class MyClass(object):
  2. def __init__(self, name):
  3. self.name = name
  4. def __enter__(self):
  5. print("__enter__方法")
  6. def __exit__(self, exc_type, exc_val, exc_tb):
  7. print("__enter__方法")
  8. obj = MyClass('kevin')
  9. with obj as f:
  10. print("开始前触发")
  11. print("结算后触发")
  12. # __enter__方法
  13. # 开始前触发
  14. # __enter__方法
  15. # 结算后触发

__getattribute__

含义

只要对象查找名字无论名字是否存在都会执行该方法,如果类中有__getattribute__方法那么就不会去执行__getattr__方法

使用

  1. class MyClass(object):
  2. def __init__(self, name):
  3. self.name = name
  4. def __getattr__(self, item):
  5. print(print("__getattr__方法", item))
  6. def __getattribute__(self, item):
  7. print("__getattribute__方法")
  8. return "这个名字是%s" % item
  9. obj = MyClass('kevin')
  10. print(obj.name)
  11. # __getattribute__方法 name
  12. # 这个名字是name

__new__

含义

__new__用于产生空对象(并不是所有的地方都可以直接调用__new__ 该方法过于底层)

真正的构造函数是new

使用

  1. # 在元类__new__里面,可以直接调用
  2. class Meta(type):
  3. def __new__(cls, *args, **kwargs):
  4. obj = type.__new__(cls, *args, **kwargs)
  5. return obj
  6. # 如果是在元类的__call__里面 需要间接调用
  7. class Mate(type):
  8. def __call__(self, *args, **kwargs):
  9. obj = object.__new__(self) # 创建一个空对象
  10. self.__init__(obj, *args, **kwargs) # 让对象去初始化
  11. return obj

笔试题

笔试题一

让字典具备句点符查找值的功能,

  1. # 定义一个类继承字典
  2. class MyDict(dict):
  3. def __getattr__(self, item):
  4. return self.get(item)
  5. def __setattr__(self, key, value):
  6. self[key] = value
  7. '''要区别是名称空间的名字还是数据k:v键值对'''
  8. obj = MyDict({'name': 'kevin', 'age': 22})
  9. # 1.具备句点符取v
  10. print(obj.name)
  11. # kevin
  12. # 2.具备句点符设k:v
  13. obj.gender = 'male'
  14. print(obj)
  15. # {'name': 'kevin', 'age': 22, 'gender': 'male'}

笔试题二

补全下列代码 使其运行不报错

  1. """
  2. class Context:
  3. pass
  4. with Context() as ctx:
  5. ctx.do_something()
  6. """
  7. class Context:
  8. def __enter__(self):
  9. return self
  10. def __exit__(self, exc_type, exc_val, exc_tb):
  11. pass
  12. def do_something(self):
  13. pass
  14. with Context() as ctx:
  15. ctx.do_something()