python 什么是magic string

如题所述

无论是python还是其它的编程语言,都有magic string这类东西存在。它并不是phtyon专有的东西。类似的还有magic number这样的。

前两年有关linux一个版本的更新就有个关于魔法数字的小插曲:

linux一个版本更新出来后,对某个类型的显卡的驱动支持出现了问题,然后相关代码被修复,其中在代码中就直接对一个地址加了一个偏移量,类似python中addr_offset += 123这样的操作,这里,这个123就是一个魔法数:它为什么是123?为什么不可以是124或者别的什么值?没有说明,没有理由,它就这么神奇的出现,然后问题就神奇的被解决了。

为此,linux项目负责人员很恼火,在项目中都说了脏话。

无论是magic string还是magic number,统称为magic value,即,魔法值。

它们在代码中突然出现,直接使用,没有说明,无从追溯。

这对代码的可读性,可维护性都带来了负面效应。

拿个简单的例子来说,在python中,我们有时会使用zipfile来处理压缩文件,比如这样:

z_file.writestr(z_name, data, zipfile.ZIP_DEFLATED)

但如果写成:

z_file.writestr(z_name, data, 8)

那么,这个8就是一个魔法值:它是什么?它哪里来的?为什么是8而不是9?除非你去读zlip的文档或源代码,否则不知道这个8是什么。而使用`zipfile.ZIP_DEFLATED`的话,即使你不了解zlip,看到这个常量名,也知道它是压缩(deflated)的zip选择了。

魔法值让我们需要了解相关很多内容时才能读懂一句代码,并且修改它的功能或修正它的bug需要同样多的精力。

再拿一个例子来说:

def getfileencode(file):
    """测试得到文本类型文件可能使用的编码格式
    它不一定就是正确的
    >>> getfileencode('errorlog.txt')
    'utf_8_sig'
    >>> getfileencode('星.txt')
    'gb18030'
    >>> getfileencode(r'D:/Python/baseweb\\app.py')
    'utf_8'
    """
    codes = ['utf_8', 'utf_16', 'gb18030', 'big5']
    with open(file, 'rb') as f:
        b = f.read()()
        for code in codes:
            try:
                b.decode(code)
                if code == 'utf_8' and b.startswith(b'\xef\xbb\xbf'):
                    code = 'utf_8_sig'
                break
            except (Exception,):
                continue
    return code

第17行中的b'\xef\xbb\xbf'就是一个魔法值,为什么是这个值?你只有了解到windows(MS)自作主张的在utf-8编码的文本文件最开始加了这么一段作为这种编码的标识时,才能理解为什么这么写。如果我们将它命名为一个常量:

UTF8_BOM = b'\xef\xbb\xbf'

然后在代码中的if这样写:

if code == 'utf_8' and b.startswith(UTF8_BOM)

你无需了解关于微软在utf-8文件前加了什么,就能知道这个判断的意思:如果它是utf-8编码,并且以BOM开始……

这是避免代码中出现魔法值的最常见的办法。

温馨提示:答案为网友推荐,仅供参考