面向对象之类的其他方法

类的其他方法

1、isinstance(obj,cls)

判断对象是否是类产生的,返回TRUE或FALSE

class Foo:
    pass
f1=Foo()
print(isinstance(f1,Foo))#True

2、issubclass(cls,super)

判断子类是否是父类产生的,返回TRUE或FALSE

class sell:
    pass
class Foo(sell):
    pass
f2=Foo()
print(issubclass(Foo,sell))#True

  

3、__getattribute__(self,item)

只要对象调用属性,不管这个属性存不存在都会触发__getattritube__的运行执行它内部的代码

使用raise功能可以做异常处理,raise AttributeError()可以让__getattr__接管运行

class Foo:
    def __init__(self,name):
        self.name=name
    def __getattr__(self, item):
        print('执行=======》getattr',item)
    def __getattribute__(self, item):
        print('执行++++++++》getattrrbute',item)
        raise AttributeError('已终止')

f1=Foo('飞乐')
# print(f1.__dict__)#执行++++++++》getattrrbute __dict__
f1.name
#执行++++++++》getattrrbute name
#执行=======》getattr name
f1.sjdlkf
#执行++++++++》getattrrbute sjdlkf
#执行=======》getattr sjdlkf
__getattribute__(self,item)

4、get,set,del,的item*方法

中括号[]操作方式和item相关,点的操作方式和attr相关

item方法和attr方法类似区别在于一个用点找属性,一个用[]中括号找属性

class Foo:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __getitem__(self, item):
        print('在执行----》getitem')
    def __setitem__(self, key, value):
        print('在执行---->setattr')
        self.__dict__[key]=value
    def __delitem__(self, key):
        print('正在执行---->delitem')
f1=Foo('飞乐',18)
print(f1.__dict__)#{'name': '飞乐', 'age': 18}
f1.sex='male'#没有触发setitem
print(f1.__dict__)#{'name': '飞乐', 'age': 18, 'sex': 'male'}
f1['age']=16#在执行---->setattr
print(f1.__dict__)#{'name': '飞乐', 'age': 16, 'sex': 'male'}
f1.age#没有触发getitem
f1['age']#在执行----》getitem
f1['sdjfkl']#在执行----》getitem
item*

5、str控制输出

改变对象的字符串显示,控制输出内容

class Foo:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return '名字是:%s ,年龄是:%s'%(self.name,self.age)
f1=Foo('飞乐',18)
print(f1)#名字是:飞乐 ,年龄是:18
#实际调用方式:str(f1)------>f1.__str__()
print(str(f1))#名字是:飞乐 ,年龄是:18
print(f1.__str__())#名字是:飞乐 ,年龄是:18
__str__(self)

6、repr控制输出

str和repr都是控制输出功能,区别repr是在解释器中使用的

class Foo:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    # def __str__(self):
    #     return '这是str'
    def __repr__(self):
        return '名字是:%s 年龄是:%s'%(self.name,self.age)
f1=Foo('飞乐',18)
print(f1)#这是str
#实际运行:repr(f1)------>f1.__repr__()
#如果没有str方法就会去找repr作为替代品
print(f1)#名字是:飞乐 年龄是:18
repr

7、__format__(self,format_spec)控制输出格式

 利用format方法格式化输出

 1 #平时使用的format格式化方法
 2 a='{0}{0}{0}'.format('飞乐')
 3 print(a)#飞乐飞乐飞乐
 4 
 5 #面向对象中使用(这个方式太low)
 6 class Date:
 7     def __init__(self,year,month,day):
 8         self.year=year
 9         self.month=month
10         self.day=day
11 d1=Date(2018,10,1)
12 x='{0.year}{0.month}{0.day}'.format(d1)
13 y='{0.year}:{0.month}:{0.day}'.format(d1)
14 z='{0.year}-{0.month}-{0.day}'.format(d1)
15 print(x)#2018101
16 print(y)#2018:10:1
17 print(z)#2018-10-1
18 
19 
20 #====================>low的升级版
21 
22 data_dict={
23     'ymd':'{0.year}{0.month}{0.day}',
24     'y:m:d':'{0.year}:{0.month}:{0.day}',
25     'y-m-d':'{0.year}-{0.month}-{0.day}',
26 }
27 
28 class Date:
29     def __init__(self,year,month,day):
30         self.year=year
31         self.month=month
32         self.day=day
33     def __format__(self, format_spec):
34         #format执行必须返回一个字符串类型,
35         #format_spec是什么内容就打印什么内容
36         print('执行———》format',format_spec)
37         #此处加个判断:当输入不规则格式时,提供默认格式
38         if not format_spec or not format_spec in data_dict:
39             format_spec='y-m-d'
40         fm=data_dict[format_spec]
41         return fm.format(self)
42 
43 d1=Date('2018','10','1')
44 print(d1.__dict__)#{'year': '2018', 'month': '10', 'day': '1'}
45 #format(d1)=====>d1.__format__()
46 print(format(d1,'ymd'))#执行———》format ymd  2018101
47 print(format(d1,'y:m:d'))#执行———》format y:m:d  2018:10:1
48 print(format(d1,'y-m-d'))#执行———》format y-m-d  2018-10-1
49 print(format(d1,'sss'))#执行———》format sss  2018-10-1
__format__(self,format_spec)

8、__slots__是什么?

它是一个类变量,变量值可以是列表,元组,或者可迭代对象,也可以是一个字符串,利用slots可以省内存(怎么省的我也不知道^_^)

它如果定义在类中,产生的实例不再有__dict__方法

class Foo:
    #此处列表里有多少属性只能设置多少属性
    __slots__ = ['name','age']

f1=Foo()
# print(f1.__dict__)#没有__dict__方法   AttributeError: 'Foo' object has no attribute '__dict__'
f1.name='飞乐'#----->setattr------>f1.__dict__['name']='飞乐'
print(f1.name)#飞乐
print(f1.__slots__)#['name', 'age']

  

9、__doc__()

doc属性是无法被继承的

class Foo:
    '我是描述信息'
    pass
class Bar(Foo):
    pass

print(Foo.__doc__)#我是描述信息
print(Bar.__doc__)#None

  

10、__del__(self)析构方法

当对象在内存中被释放时,自动触发执行

class Foo:
    def __init__(self,name):
        self.name=name
    def __del__(self):
        print('我执行了')
f1=Foo('飞乐')
# del f1  #我执行了
print('------------------------>')#------------------------>

  

11、__call__(self,*arg,**kwargs)

对象后面加括号,触发执行

class Foo:
    def __call__(self, *args, **kwargs):
        print('实例执行了 obj()')

f1=Foo()#触发了call方法

f1()#Foo下面的__call__实例执行了 obj()

Foo()#xxx下的__call

  

12、迭代器协议

 1 class Foo:
 2     def __init__(self,n):
 3         self.n=n
 4     #加iter方法成为可迭代对象
 5     def __iter__(self):
 6         return self
 7 
 8     def __next__(self):
 9         if self.n==100:
10             raise StopIteration('终止了')
11         self.n+=1
12         return self.n
13 
14 # l=list('hello')
15 # for i in l:
16 #     print(i)
17 
18 f1=Foo(10)
19 print(f1.__next__())
20 print(next(f1))
21 for i in f1:  #obj=f1.__iter__() ====== iter(f1)
22     print(i)   #obj.__next__()
View Code

2、迭代器协议实现斐波那契数列

 1 class Fib:
 2     def __init__(self):
 3         self._a=1
 4         self._b=1
 5     def __iter__(self):
 6         return self
 7     def __next__(self):
 8         if self._a>100:
 9             raise StopIteration('已终止')
10         self._a,self._b=self._b,self._a + self._b
11         return self._a
12 
13 f1=Fib()
14 print(next(f1))
15 print(next(f1))
16 print(next(f1))
17 print('===================')
18 for i in f1:
19     print(i)
View Code

13、描述符

数据描述符分两种一种是数据描述符:至少实现了__get__()和__set__()

第二种是非数据描述符:没有实现__set__()

描述符优先级排序:类属性>数据描述符>实例属性>非数据描述符>找不到,找不到的属性触发__getattr__()

 1 class Foo:
 2     def __get__(self, instance, owner):
 3         print('======>get')
 4     def __set__(self, instance, value):
 5         print('=======>set')
 6         instance.__dict__['x']=value #f1.__dict__
 7     def __delete__(self, instance):
 8         print('=======>del')
 9 
10 class Bar:
11     x=Foo()#在实例化时x会被Foo代理
12     def __init__(self,n):
13         self.x=n#b1.x=10
14 
15 b1=Bar(10)#初始化时设置属性会被Foo里面的set代理打印 =======>set
16 print(b1.__dict__)#{'x': 10}
17 b1.x=11111#被代理打印=======>set
18 print(b1.__dict__)#{'x': 11111}
19 
20 b1.y=22222222222
21 print(b1.__dict__)#{'x': 11111, 'y': 22222222222}
View Code
原文地址:https://www.cnblogs.com/happyfei/p/9635854.html