文章目录
一、面向对象常见双下方法
1._ _ str_ _
在打印或在前端显示对象的操作时时会自动调用_ _ str _ _方法,方法必须返回一个字符串类型的数据
class Akb(object):
def __str__(self):
print("__str__被调用")
return "45"
a = Akb()
print(a)
2._ _ del _ _
该方法在对象主动或被动进行删除操作时会调用
class Akb(object):
def __del__(self):
print("__del__被调用")
print("创建对象")
a = Akb()
print("删除对象")
del a
print("创建对象")
a = Akb()
print("运行结束")
3._ _ getattr_ _
对象查找不存在的名称时触发
class Abk(object):
def __getattr__(self, item):
raise Exception("这个错误提示已被改变")
a = Abk()
a.name
4._ _ setattr_ _
对象在添加变量时调用_ _ setattr_ _方法(创建对象时调用 _ _ init _ _方法也会调用)
class Abk(object):
def __init__(self, name):
self.name = name
def __setattr__(self, key, value):
super().__setattr__(key, value)
print("__strattr__被调用")
a = Abk("kkx")
a.age = 18
5._ _ call_ _
对象加括号调用后会自动调用该方法
class Abk(object):
def __call__(self, *args, **kwargs):
print("__call__方法被调用", *args, **kwargs)
a = Abk()
print(a())
a("key")
6. _ _ entar _ _和 _ _ exit _ _
对象执行with上下文管理语法开始时自动调用_ _ entar _ _
对象执行with上下文管理语法结束时自动调用_ _ exit _ _
俩个方法需要配套使用
class Abk(object):
def __enter__(self):
print("开始with上下文管理语法,调用__enter__方法")
def __exit__(self, exc_type, exc_val, exc_tb):
print("结束with上下文管理语法,调用__exit__方法")
def create_o():
return Abk()
with create_o() as a :
print(type(a))
7. _ _ getattribute _ _
只要在对象中查找名称,无论该名称是否存在都会调用
class Abk(object):
def __getattribute__(self, item):
print("你在寻找%s"%item)
a = Abk()
a.name
8. _ _ new _ _
产生一个空的对象,类在被调用时先调用的_ _ new _ _ 生成空对象再用 _ _ init _ _ 生成实例化对象
def __new__(cls, *args, **kwargs):
return type.__new__(cls, *args, **kwargs)
二、元类
用于产生类的类,类是不能通过继承的方式直接指定
使用元类可以高度定制类的行为
1.元类的定义
# 自定义元类
class MyMeta(type): # 自定义元类必须继承type,否则就是普通的类
'''
早于__init__方法执行,必须返回空对象,由于该方法是调用类后第一个运行的方法,此时并没有对象产生,因此该方法的第一个参数必须是类本身(MyMeta),*args, **kwargs用来接收调用元类产生对象所需的参数(类名 类的基类 名称空间)
'''
def __new__(cls,*args, **kwargs):
return type.__new__(cls, *args, **kwargs) # 直接调用父类type中的__new__方法
'''
通过__init__控制类的产生,调用自定义元类与调用内置元类type的方式相同,需要传入类名、类的父类们、类体代码的名称空间,__init__方法中第一个参数来自于__new__方法产生的空对象。
'''
def __init__(self, class_name, class_bases, class_dict):
'''
在该方法内可以控制类的产生
'''
if not class_name.istitle(): # 实现类名首字母必须大写,否则抛出异常
raise NameError('类名的首字母必须大写')
2.元类的使用
class C1(metaclass=MyTypeClass):# 将继承元类的类作为关键字参数引入
pass