__init__
类名() 自动执行 __init__
class Foo:
def __init__(self):
print("k")
obj=Foo()
__call__
对象() 自动执行 __call__
class Foo:
def __init__(self):
print("k") #k
def __call__(self, *args, **kwargs):
print(args) #(1, 2, 3)
return "call"
obj=Foo()
ret=obj(1,2,3)
print(ret) #call
__setattr__,__delattr__,__getattr__
class Foo:
def __init__(self, name):
self.name = name
def __getitem__(self, item):
return "k"
def __setitem__(self, key, value):
print(key,value) #kaix ll
def __delitem__(self, key):
print(key)
obj = Foo("ll")
ret = obj["name"] #对象['xx'] 自动执行 __getitem__
obj["kaix"]="ll" #对象['xx'] = 11 自动执行 __setitem__ 无返回值
del obj["uuu"] # 对象[xx] 自动执行 __delitem__
print(ret)
__add__
class Foo:
def __init__(self,a1,a2):
self.a1=a1
self.a2=a2
def __add__(self, other):
return self.a2+obj2.a1
obj1 = Foo(1,2)
obj2 = Foo(88,99)
ret = obj1 + obj2 #90
print(ret)
__enter__和__exit__
上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法
class Foo:
def __init__(self, a1, a2):
self.a1 = a1
self.a2 = a2
def __enter__(self):
print("a1")
return "a2"
def __exit__(self, exc_type, exc_val, exc_tb):
print("a3")
obj = Foo(1, 2)
with obj as f:
print(f)
print('内部代码')
# a1
# a2
# 内部代码
# a3
__exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则with后的代码都无法执行
class Open:
def __init__(self,name):
self.name=name
def __enter__(self):
print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
def __exit__(self, exc_type, exc_val, exc_tb):
print('with中代码块执行完毕时执行我啊')
print(exc_type)
print(exc_val)
print(exc_tb)
return True
with Open('a.txt') as f:
print('=====>执行代码块')
raise AttributeError('***着火啦,救火啊***')
print('0'*100) #------------------------------->会执行
如果__exit()返回值为True,那么异常会被清空,就好像啥都没发生一样,with后的语句正常执行
__str__,__repr__
class Student():
def __init__(self, name, age):
self.name = name
self.age = age
"""
1. 打印对象的时候,输出对象的时候会自动触发类中得__str__方法
2. 返回值必须是字符串形式
3. 如果它跟__repr__方法同时存在,__str__的优先级更高
"""
def __str__(self): # 这个用的是最多的
print('str')
return 'from str'
def __repr__(self):
print('repr')
return 'from repr'
stu = Student('ly', 20)
# print(stu) # <__main__.Student object at 0x00000226AC4F5A60>
# print('repr:', repr(stu))
print('str:', str(stu))
__del__
class MySQL:
def __init__(self, ip, port):
self.ip = ip
self.port = port
self.f = open('a.txt', 'w')
"""
1.当你删除对象的时候会触发__del__的执行
2. 当整个脚本的程序都执行完毕的时候,也会触发__del__的执行
3. 一般用在用来在对象被删除时自动触发回收系统资源的操作
"""
def __del__(self):
print('from _del')
self.f.close()
mysql = MySQL('127.0.0.1', 3306)
print('1223')
print('1223')
print('1223')
print('1223')
print('1223')
isinstance(obj,cls)和issubclass(sub,super)
isinstance(obj,cls)检查是否obj是否是类 cls 的对象
class Foo:
pass
obj=Foo()
print(isinstance(obj, Foo)) #True
issubclass(sub, super)检查sub类是否是 super 类的派生类
class Foo(object):
pass
class Bar(Foo):
pass
print(issubclass(Bar, Foo)) #True
__setattr__,__delattr__,__getattr__
class Foo:
x=1
def __init__(self,y):
self.y=y
def __getattr__(self, item):
print('----> from getattr:你找的属性不存在')
def __setattr__(self, key, value):
print('----> from setattr')
# self.key=value #这就无限递归了,你好好想想
# self.__dict__[key]=value #应该使用它
def __delattr__(self, item):
print('----> from delattr')
# del self.item #无限递归了
self.__dict__.pop(item)
#__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)
#__delattr__删除属性的时候会触发
f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a
print(f1.__dict__)
#__getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx
__doc__
class Foo:
'我是描述信息'
pass
print(Foo.__doc__)