1. 1. 说明
  2. 2. 具体说明
    1. 2.1. 创建实例和销毁
      1. 2.1.1. __new__
      2. 2.1.2. __init__
      3. 2.1.3. __del__
    2. 2.2. 属性管理
      1. 2.2.1. __getattr__
      2. 2.2.2. __getattribute__
      3. 2.2.3. __setattr__
      4. 2.2.4. __delattr__
      5. 2.2.5. __dir__
    3. 2.3. 序列表示形式
      1. 2.3.1. __str__
      2. 2.3.2. __repr__
      3. 2.3.3. __bytes__
      4. 2.3.4. __doc__
      5. 2.3.5. __format__
    4. 2.4. 集合管理
      1. 2.4.1. __len__
      2. 2.4.2. __getitem__
      3. 2.4.3. __setitem__
      4. 2.4.4. __delitem__
      5. 2.4.5. __contains__
    5. 2.5. 迭代枚举
      1. 2.5.1. __iter__
      2. 2.5.2. __next__
    6. 2.6. 上下文管理
      1. 2.6.1. __enter__
      2. 2.6.2. __exit__
    7. 2.7. 描述符
      1. 2.7.1. __get__
      2. 2.7.2. __set__
      3. 2.7.3. __delete__

说明

主要说明类的特殊方法(也叫魔法方法),了解使用场景和方法,使用时方便查询

具体说明

创建实例和销毁

__new__
__init__
__del__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Foo01:
def __new__(cls, *args, **kwargs):
"""对象实例化调用的第一个方法,在__init__之前, args,kwargs传递给init方法"""
print('__new__')
return super().__new__(cls)
def __init__(self, name):
"""初始化实例操作"""
print('__init__')
self.name = name
def __del__(self):
""" del 时调用,或实例自行销毁时调用"""
print('__del__')
return
foo = Foo01(name='ttxs') # __init__
print(foo.name) # ttxs
del foo # __del__

属性管理

__getattr__
__getattribute__
__setattr__
__delattr__
__dir__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Foo02:
def __getattr__(self, item):
""" 该方法在访问一个不存在的属性时调用 """
print('__getattr__')
if item not in self.__dict__:
return None
return super(Foo02, self).__getattr__(item)
def __setattr__(self, key, value):
""" 该方法在对属性进行赋值和修改时调用,应该避免"无限递归"错误,如: self.name = 'xxx' """
print('__setattr__')
# self.key = value # 每一次属性赋值时, __setattr__都会被调用,因此不断调用自身导致无限递归
self.__dict__[key] = value
return super(Foo02, self).__setattr__(key, value)
def __delattr__(self, item):
""" 该方法在删除属性时调用 """
print('__delattr__')
# del self.item # 无限递归, 原因同上
return super(Foo02, self).__delattr__(item)
def __getattribute__(self, item):
""" 该方法在属性被访问时调用,调用__getattr__前必定会调用 __getattribute__ """
print('__getattribute__')
return super(Foo02, self).__getattribute__(item)
foo02 = Foo02()
foo02.abc = 'abc' # 调用__setattr__方法
print(foo02.abc) # 调用__getattribute__方法
print('error---', foo02.x) # 调用__getattr__方法
foo02.__dict__ # 调用__getattribute__方法
del foo02.abc # 调用__delattr__方法

序列表示形式

__str__
__repr__
__bytes__
__doc__
__format__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Foo03:
""" 文档展示说明表示 (__doc__)"""
def __init__(self, name, id):
self.name = name
self.id = id
def __repr__(self):
""" 主要针对程序的调试,调用和使用,如果定义了str函数print会调用str,没有就调用repr函数 """
print('__repr__')
return '%s with %s id' % (self.name, self.id)
def __str__(self):
"""print方法时调用"""
print('__str__')
return self.name.capitalize()
def __bytes__(self):
print('__bytes__')
return '%s in bytes is %s' % (self.name, self.id)
def __format__(self):
""" 调用format方法时 """
print('__format__')
return '%s in format is %s' % (self.name, self.id)
foo03 = Foo03(name='ttxsgoto', id=666)
print(Foo05.__doc__) # 说明文档信息
print(foo05) # __str__()方法
f = Foo03(name='ttxsgoto', id=666)
f.__format__()
ff = bytes(f) # bytes调用

集合管理

__len__
__getitem__
__setitem__
__delitem__
__contains__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class Foo04:
def __init__(self, value):
if value is None:
self.value = {}
else:
self.value = value
def __len__(self):
"""表示集合长度"""
return len(self.value)
def __getitem__(self, item):
"""执行self[item],调用该方法"""
print('__getitem__')
return self.value[item]
def __setitem__(self, key, value):
"""执行self[key]=value,调用该方法"""
print('__setitem__')
self.value[key] = value
def __delitem__(self, key):
"""执行 del self[key],调用该方法"""
print('__delitem__')
del self.value[key]
def __contains__(self, item):
"""判断item是否在容器中,调用该方法in/not in,如 item in container"""
print('__contains__')
if item in self.value:
return True
return False
foo04 = Foo04(value={'a': 'a'})
foo04['xx'] = 'abc' # 调用__setitem__方法
print(foo04['xx']) # 调用__getitem__方法
print(len(foo04)) # 调用__len__方法
if 'xx' in foo04: # 调用__contains__方法
print('ok')
else:
print('error')

迭代枚举

__iter__
__next__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import re
import reprlib
from collections import abc
RE_WORD = re.compile('\w+')
class Foo04:
""" 通过索引从文本中提取单词 """
def __init__(self, text):
self.text = text
self.words = RE_WORD.findall(text)
def __iter__(self):
""" 可迭代对象 """
return SentenceIterator(self.words)
def __len__(self, index):
return len(self.words)
def __repr__(self):
return 'Sentence(%s)' % reprlib.repr(self.text) # 用于生成大型数据结构的简略字符串表示形式, 默认情况下最多30个字符
class SentenceIterator:
""" 迭代器 """
def __init__(self, words):
self.words = words
self.index = 0
def __next__(self):
""" 返回下一个可用的元素,如果没有,抛出StopIteration异常 """
try:
word = self.words[self.index]
except IndexError:
raise StopIteration()
self.index += 1
return word
def __iter__(self):
""" 返回self,以便在应该使用可迭代对象的地方使用迭代器 """
return self
foo04 = Foo04(text='"The time has come," the Walrus said,')
print(foo04)
print(iter(foo04))
for foo in foo04:
print(foo)
print(issubclass(SentenceIterator, abc.Iterator))

上下文管理

__enter__
__exit__

参考链接
https://ttxsgoto.github.io/2017/04/11/python-contextlib/

描述符

__get__
__set__
__delete__

参考链接
https://ttxsgoto.github.io/2018/01/31/descriptor/
https://ttxsgoto.github.io/2018/02/01/python-descriptor02/