Python 小手册

对象析构 | 字符处理

Posted by luoruiqing on January 1, 1999

数据操作

缓存属性

1
2
3
4
5
6
7
8
9
try:
    from functools import cached_property  # py38+
except ImportError:
    from django.utils.functional import cached_property # 需要安装django


@cached_property
def a():
    return 1

定长列表

1
2
from collections import deque # 定长列表

文件类

清除文件

1
2
3
4
5
6
7
8
from glob import glob
import os

items = ["*.flv", "*.mp4", "*.f4v", "../*.flv", "../*.mp4", "../*.pyc", "../*.download"]
for item in items:
    for file in glob(item):
        if os.path.exists(file):
            os.remove(file)

定制

错误定制

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
class BaseError(BaseException):
    """ 自定义错误基类 """
    CODES = {}  # 所有错误


class Error(BaseError):
    ''' 自定义错误类 '''
    status_code = 400  # 默认错误响应状态码
    code = None  # 错误代码
    message = ''  # 错误消息

    def __new__(cls, code, *args, **kwargs):
        check = kwargs.pop('check', True)
        instance = super().__new__(cls, code, *args, **kwargs)
        if check:
            assert code not in instance.CODES, f"Error code duplication: {code}."
            instance.CODES[code] = instance  # 记录错误实例
        return instance

    def __init__(self, code, message, status_code=400, *args, **kwargs):
        ''' 带参数进入格式化到消息体 '''
        self.code = code
        self.message = message
        self.status_code = status_code

    def __call__(self, *args, **kwargs):
        ''' 回调始终生成新的错误对象, 且code不允许变化 '''
        message = (self.message.format(*args, **kwargs)) if args or kwargs else self.message

        return self.__class__(
            code=self.code,
            message=message,
            status_code=self.status_code,
            check=False,
        )

    def __str__(self):
        return f'Error {self.code}({self.status_code}): {self.message}.'


if __name__ == "__main__":
    import unittest

    class TestError(unittest.TestCase):
        ''' 单元测试 '''

        def tearDown(self):
            Error.CODES.clear()  # 清除

        def test_error_code_duplication(self):
            ''' 测试错误代码重复 '''
            ERROR1 = Error(10000, '这是个错误! {}')
            with self.assertRaises(AssertionError):
                ERROR2 = Error(10000, '这是个错误! {}')

        def test_error_repeat_call(self):
            ''' 测试多次调用同一实例 '''
            ERROR1 = Error(10000, '这是个错误! {}')
            temporary_error_1 = ERROR1('附加信息1')
            self.assertEqual(temporary_error_1.code, 10000)
            self.assertEqual(temporary_error_1.message, '这是个错误! 附加信息1')
            temporary_error_2 = temporary_error_1('附加信息2')
            self.assertEqual(temporary_error_2.code, 10000)
            self.assertEqual(temporary_error_2.message, '这是个错误! 附加信息1')

        def test_error_type_checking(self):
            ''' 测试实例类型 '''
            ERROR1 = Error(10000, '这是个错误! {}')
            self.assertIsInstance(ERROR1, Error)
            temporary_error_1 = ERROR1('附加信息1')
            self.assertIsInstance(temporary_error_1, Error)
            temporary_error_2 = temporary_error_1('附加信息2')
            self.assertIsInstance(temporary_error_2, Error)

            self.assertTrue(issubclass(ERROR1.__class__, BaseError))

    unittest.main()

错误位置

获取所有类