面向对象进阶
一:isinstance(obj,cls)和issubclass(sub,super)
- isinstance(obj,cls)检查是否obj是否是类 cls 的对象
class Foo:
pass
f1=Foo()
print(isinstance(f1,Foo))
2. issubclass(sub, super)检查sub类是否是 super 类的派生类
class Foo:
pass
f1=Foo()
print(isinstance(f1,Foo))
class Bar(Foo):
pass
b1=Bar()
print(issubclass(Bar,Foo))
print(isinstance(b1,Foo))
print(type(b1)) #<class '__main__.Bar'>
二:getattribute
class Foo:
def __init__(self,x):
self.x=x
def __getattr__(self, item):
print('执行的是getattr')
def __getattribute__(self, item):
print('执行的是getattribute')
raise AttributeError('抛出异常了')
f1=Foo(10)
f1.xxxxx
f1.x
属性有没有都会触发getattribute,当由于raise AttributeError('抛出异常了'),使得触发getattr
当__getattribute__与__getattr__同时存在,只会执行__getattrbute__,除非__getattribute__在执行过程中抛出异常AttributeError
三:item方法
- __getitem__
- __setitem__
- __delitem__
class Foo:
def __getitem__(self, item):
print('getitem',item)
return self.__dict__[item]
def __setitem__(self, key, value):
print('setitem')
self.__dict__[key]=value
def __delitem__(self, key):
print('delitem')
self.__dict__.pop(key)
f1=Foo()
# print(f1.__dict__)
f1['name']='egon'
f1['age']=18
print(f1.__dict__)
#
del f1['name']
print(f1.__dict__)
print(f1['age'])
item 方法适用于字典触发,而 .形式适用于attr属性触发方法
四:改变对象的字符串显示
class Foo:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self): #str(f1)-->f1.__str__,print()触发
return '名字是%s 年纪是%s'%(self.name,self.age) #自己控制打印信息
f1=Foo('egon',18)
print(f1) #<__main__.Foo object at 0x005B2510>;名字是egon 年纪是18
class Foo:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '这是str'
def __repr__(self): #repr(f1)-->f1.__repr__,应用在解释器中
return '名字是%s 年纪是%s'%(self.name,self.age) #自己控制打印信息
f1=Foo('egon',18)
print(f1) #str(f1)--->f1.__str__()---->f1.__repr___()
__str__ :由print触发 ===》obj.__str__()
__repr__:使用于交互式解释器====》obj.__repr__()
如果__str__没有定义,就使用__repr__来代替输出
notice : 这两种方法返回值必须是字符串,否则抛出异常
自定制格式化方法format
x='{0}{0}{0}'.format('dog')
print(x)#dogdogdog
class Data:
def __init__(self,year,mon,day):
self.year=year
self.mon=mon
self.day=day
d1=Data(2017,3,12)
x='{0.year}{0.mon}{0.day}'.format(d1) #d1.format
y='{0.year}:{0.mon}:{0.day}'.format(d1)
z='{0.year}-{0.mon}-{0.day}'.format(d1)
print(x)
print(y)
print(z)#20173122017:3:12
2017-3-12
format_dic={
'ymd':'{0.year}{0.mon}{0.day}',
'm-d-y':'{0.mon}{0.day}{0.year}',
'y:m:d':'{0.year}{0.mon}{0.day}',
}
class Data:
def __init__(self,year,mon,day):
self.year=year
self.mon=mon
self.day=day
def __format__(self, format_spec):
print('我执行啦')
print('--->',format_spec)
if not format_spec or format_spec not in format_dic:
format_spec='ymd'
fm=format_dic[format_spec]
return fm.format(self)
d1=Data(2017,3,12)
print(format(d1,'ymd'))
print(format(d1,'m-d-y'))
print(format(d1,'m:d:y'))
print(format(d1,'m-d:y'))
五:__slots__ :定义类变量,效果由类产生的属性不在具有__dict__属性
属性很少的类,但是实例很多,为了节省内存可以使用__slots__取代实例的__dict__
class Foo:
__slots__=['name','age']# 属性字典的形式{'name':None,'age':None}
__slots__ = 'name' # {'name':None,'age':None}
f1=Foo()
# print(f1.__dict__) #报错,取消了__dict__
print(f1.__slots__) #['name', 'age']
f2=Foo()
print(f2.__slots__)
f2.name='alex'
f2.age=19
print(f2.name)
print(f2.age)
#f1与f2都没有属性字典__dict__了,统一归__slots__管,节省内存
六:
1. __doc__ 改属性无法被继承,文档注释
class Foo:
'我是描述信息'
pass
print(Foo.__doc__)
class Foo:
'我是描述信息'
pass
class Bar(Foo):
pass
print(Bar.__doc__) #改属性无法继承给子类
print(Foo.__doc__)
2. __module__表示当前操作的对象在那个模块
__class__表示当前操作的对象的类是什么
from lib.aa import C
c1=C()
print(c1.name)
print(c1.__module__)
print(c1.__class__)
#aa.py
class C:
def __init__(self):
self.name='SB'
3. __del__析构方法 当对象在内存中被释放时,自动触发执行,只在实例被删除时触发
class Foo:
def __init__(self,name):
self.name=name
def __del__(self):
print('wozhixing')
f1=Foo('alex')
# del f1
# print('---------------->') #先执行后打印
del f1.name #只有实例被删除时才触发,所以先打印,然后再删除 这里的实例是f1
print('---------------->') #先打印后删除
4. __call__对象后面加括号,触发执行
class Foo:
def __call__(self, *args, **kwargs):
print('实例执行啦')
f1=Foo()
f1() #Foo下的__cal__
Foo()#abc下的__cal__
5. 迭代器协议

class Foo:
def __init__(self,n):
self.n=n
def __iter__(self): #把一个对象变成可迭代对象
return self
def __next__(self):
if self.n == 13:
raise StopIteration('终止了')
self.n+=1
return self.n
f1=Foo(10)
print(iter(f1))
#第一种方法
for i in f1: #f1.__iter__() == iter(f1)
print(i)
#第二种方法:
print(f1.__next__())
print(f1.__next__())
print(f1.__next__())
print(f1.__next__())
例子:菲波那切数列实现
class Fib:
def __init__(self):
self._a=1
self._b=1
def __iter__(self):
return self
def __next__(self):
if self._a > 100:
raise StopIteration('终止了')
self._a,self._b=self._b,self._a + self._b
return self._a
f1=Fib()
print(next(f1))
print(next(f1))
print(next(f1))
print(next(f1))
print(next(f1))
print(next(f1))
print('==================================')
for i in f1:
print(i)#
1
2
3
5
8
13
==================================
21
34
55
89
144
来源:https://www.cnblogs.com/xyd134/p/6541910.html