day6-面向对象补充篇--类的特殊成员
先说明一下,今天的内容主要转自师兄张其高的博客http://www.cnblogs.com/zhangqigao/articles/6935221.html
前面我们讲了类的方法,有普通方法,就是我们自己定义的方法,还有静态方法,类方法,属性方法,其实类还有另外一种方法,叫做类的特殊成员方法。这里就把主要的类的特殊成员方法大概讲解一下。
- __doc_
表示类的描述信息
1 class Dog(object): 2 """此类是形容Dog这个类""" #类的描述信息 3 4 def __init__(self,name): 5 self.name = name 6 7 8 print(Dog.__doc__) #打印类的描述信息 9 10 #输出 11 此类是形容Dog这个类
- __module__和__class__
说明:
- __module__: 表示当前操作的对象在哪个模块
- __class__:表示当前操作的对象的类是什么
aa.py的代码:
1 class C(object): 2 3 def __init__(self): 4 self.name = "Alex"
index.py的代码:
1 from lib.aa import C 2 3 obj = C() 4 5 print(obj.__module__) #表示当前操作的对象在哪个模块 6 print(obj.__class__) #表示当前操作的对象的类是什么 7 8 #输出 9 lib.aa 10 <class 'lib.aa.C'>
- __init__
说明:构造方法,通过类创建对象时,自动触发执行,这里不再赘述举例了。
- __del__
说明:析构方法,当对象在内存中被释放时,自动触发执行
(1) 注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,
(2) 所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
- __call__
说明: 对象后面加括号,触发执行
1 class Foo(object): 2 def __init__(self): 3 self.name = "Alex" 4 5 def __call__(self, *args, **kwargs): #重写call方法 6 print("running call",args,kwargs) 7 8 f = Foo() #执行__init__ 9 f(1,2,3,name=333) # 执行call方法,也可以写成 Foo()(1,2,3,name=333) 10 11 #输出 12 running call (1, 2, 3) {'name': 333}
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
- __dict__
说明: 查看类或对象中的所有成员
①类.__dict__
效果:打印类中所有的属性,不包括实例属性
1 class Province(object): 2 3 country = 'China' 4 5 def __init__(self, name, count): 6 self.name = name 7 self.count = count 8 9 def func(self, *args, **kwargs): 10 print("func") 11 12 print(Province.__dict__) #类.__dict__ 13 14 #输出 15 {'__doc__': None, '__weakref__': <attribute '__weakref__' of 'Province' objects>, '__init__': 16 <function Province.__init__ at 0x00000247F3CAD488>, 'country': 'China', '__dict__': 17 <attribute '__dict__' of 'Province' objects>, 'func': <function Province.func at 18 0x00000247F3CAD510>, '__module__': '__main__'} #打印类中所有的属性,不包括实例属性
②实例名.__dict__
效果:打印该实例的所有属性,不包括类属性
1 class Province(object): 2 3 country = 'China' 4 5 def __init__(self, name, count): 6 self.name = name 7 self.count = count 8 9 def func(self, *args, **kwargs): 10 print("func") 11 12 p = Province("jiangsu",20000) #实例化 13 print(p.__dict__) #实例名.__dict__ 14 15 #输出 16 {'count': 20000, 'name': 'jiangsu'} #打印该实例的所有属性,不包括类属性
- __str__
说明:如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值
1 class Province(object): 2 3 country = 'China' 4 5 def __init__(self, name): 6 self.name = name 7 8 def __str__(self): 9 return "<obj:{0}>".format(self.name) 10 11 p = Province("jiangsu") 12 print(p) #打印这个对象 13 14 #输出 15 <obj:jiangsu> #给对象重新起了一个名字
注:这个以后会在django框架里面会用到,这边就不多说了
- __getitem__、__setitem__、__delitem__
说明:用于索引操作,如字典。以上分别表示获取、设置、删除数据
1 class Foo(object): 2 3 def __getitem__(self, key): 4 print('__getitem__:',key) 5 6 def __setitem__(self, key, value): 7 print('__setitem__:',key,value) 8 9 def __delitem__(self, key): 10 print('__delitem__',key) 11 12 13 f = Foo() 14 f["name"] = "shuaigaogao" #自动触发__setitem__方法 15 f["name"] #自动触发__getitem__方法 16 del f["name"] #自动触发__delitem__方法 17 18 #输出 19 __setitem__: name shuaigaogao 20 __getitem__: name 21 __delitem__ name
注:这边的__delitem__没有做真正的删除,只是触发这个方法,想要真正删除,只需要在__delitem__函数中添加删除功能即可
以下内容转自老师的博客http://www.cnblogs.com/wupeiqi/p/4766801.html
- __getslice__、__setslice__、__delslice__
这三个方法用于分片操作,如:列表
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 class Foo(object): 5 6 def __getslice__(self, i, j): 7 print '__getslice__',i,j 8 9 def __setslice__(self, i, j, sequence): 10 print '__setslice__',i,j 11 12 def __delslice__(self, i, j): 13 print '__delslice__',i,j 14 15 obj = Foo() 16 17 obj[-1:1] # 自动触发执行 __getslice__ 18 obj[0:1] = [11,22,33,44] # 自动触发执行 __setslice__ 19 del obj[0:2] # 自动触发执行 __delslice__
- __iter__
用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__
第一步:
1 class Foo(object): 2 pass 3 4 5 obj = Foo() 6 7 for i in obj: 8 print i 9 10 # 报错:TypeError: 'Foo' object is not iterable
第二步:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 class Foo(object): 5 6 def __iter__(self): 7 pass 8 9 obj = Foo() 10 11 for i in obj: 12 print i 13 14 # 报错:TypeError: iter() returned non-iterator of type 'NoneType'
第三步:
1 # !/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 class Foo(object): 5 6 def __init__(self, sq): 7 self.sq = sq 8 9 def __iter__(self): 10 return iter(self.sq) 11 12 obj = Foo([11,22,33,44]) 13 14 for i in obj: 15 print(i) 16 17 输出: 18 11 19 22 20 33 21 44
以上步骤可以看出,for循环迭代的其实是 iter([11,22,33,44]) ,所以执行流程可以变更为:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 obj = iter([11,22,33,44]) 5 6 for i in obj: 7 print(i)
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 obj = iter([11,22,33,44]) 5 6 while True: 7 val = obj.next() 8 print val