内置方法
Python
的Class
机制内置了很多特殊的方法来帮助使用者高度定制自己的类,这些内置方法都是以双下划线开头和结尾的,会在满足某种条件时自动触发
__str__
含义
__str__
方法会在对象被打印(print
)操作的时候,自动触发,该方法必须返回字符串类型的数据。很多时候用来更加精准的描述对象
使用
class MyClass(object):
def __init__(self, name):
self.name = name
def __str__(self):
"""该方法必须返回字符串类型的数据"""
return "对象:%s" % self.name
obj = MyClass('kevin')
# print(obj) # (没有__str__)
# <__main__.MyClass object at 0x7fd2bb457860>
print(obj)
# 对象:kevin
print(MyClass)
# <class '__main__.MyClass'>
__del__
含义
__del__
方法会在对象被执行(被动、主动)删除操作之后自动执行。
Python
的垃圾回收机制会自动清理Python
程序的资源,当一个对象只占用应用程序级资源时,完全没必要为对象定制__del__
方法,但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下,关于系统资源的回收,Python
的垃圾回收机制便派不上用场了,需要我们为对象定制该方法,用来在对象被删除时自动触发回收系统资源的操作
使用
被动删除
class MyClass(object):
def __init__(self, name):
self.name = name
def __del__(self):
"""对象被执行删除操作之后执行(垃圾回收机制)"""
print("__del__什么时候执行")
obj = MyClass('kevin')
print("被动删除")
# 被动删除
# __del__什么时候执行
主动删除
class MyClass(object):
def __init__(self, name):
self.name = name
def __del__(self):
"""对象被执行删除操作之后执行"""
print("__del__什么时候执行")
obj = MyClass('kevin')
"""主动删除"""
del obj
# __del__什么时候执行
print("主动删除")
# 主动删除
__getattr__
含义
__getattr__
方法会在对象查找不存在的“名字”时候自动触发
使用
class MyClass(object):
def __init__(self, name):
self.name = name
def __getattr__(self, item):
"""对象查找不存在名字的时候自动触发"""
return "不好意思,没有%s这个名字" % item # item 表示不存在的"名字",类型是字符串
obj = MyClass('kevin')
print(obj.name)
# kevin
print(obj.age)
# 不好意思,没有age这个名字
__setattr__
含义
__setattr__
方法在对象添加属性操作的时候自动触发
使用
class MyClass(object):
def __init__(self, name):
self.name = name
def __setattr__(self, key, value):
"""对象在执行添加属性操作的时候自动触发>>>obj.变量名=变量值"""
print("__setattr__方法")
print(key, value)
obj = MyClass('kevin')
# __setattr__方法
# name kevin
print(obj.__dict__) # 因为重写了__setattr__,赋值操作都会触发它的运行,根本没赋值,除非直接接操作属性字典,否则永远无法赋值
# {}
obj.age = 22
# __setattr__方法
# age 22
print(obj.__dict__) # 因为重写了__setattr__,赋值操作都会触发它的运行,根本没赋值,除非直接接操作属性字典,否则永远无法赋值
obj.__dict__['name'] = 'tony'
print(obj.__dict__)
# {'name': 'tony'}
__call__
含义
__call__
方法在对象被加括号调用的时候自动触发,使实例的对象能够像函数一样被调用
使用
class MyClass(object):
def __init__(self, name):
self.name = name
def __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 = name
def __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 = name
def __getattr__(self, item):
print(print("__getattr__方法", item))
def __getattribute__(self, item):
print("__getattribute__方法")
return "这个名字是%s" % item
obj = 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.具备句点符取v
print(obj.name)
# kevin
# 2.具备句点符设k:v
obj.gender = 'male'
print(obj)
# {'name': 'kevin', 'age': 22, 'gender': 'male'}
笔试题二
补全下列代码 使其运行不报错
"""
class Context:
pass
with Context() as ctx:
ctx.do_something()
"""
class Context:
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
pass
def do_something(self):
pass
with Context() as ctx:
ctx.do_something()