我的代码中使用Python检测文本文件编码的缺陷?

Mat*_*ell 5 python encoding text-files

我比Python或文本编码更了解自行车修理,电锯使用和沟槽安全; 考虑到这一点...

Python的文本编码似乎是一个长期的问题(我自己的问题:?搜索文本文件与Python的各种编码的内容,和其他人我读过:1,2我已经采取了尝试写一些代码来猜测.编码如下.

在有限的测试中,这段代码似乎可以用于我的目的*,而不必知道文本编码的前三个字节以及这些数据不提供信息的情况.

*我的目的是:

  1. 有一个无依赖性的代码片段,我可以使用中等程度的成功,
  2. 扫描本地工作站以查找任何编码的基于文本的日志文件,并根据其内容将其识别为我感兴趣的文件(这需要使用正确的编码打开文件)
  3. 让这个工作的挑战.

:什么是用一个什么,我认为是比较和像我这样做如下计算字符的klutzy方法的缺陷?任何输入都非常感谢.

def guess_encoding_debug(file_path):
    """
    DEBUG - returns many 2 value tuples
    Will return list of all possible text encodings with a count of the number of chars
    read that are common characters, which might be a symptom of success.
    SEE warnings in sister function
    """

    import codecs
    import string
    from operator import itemgetter

    READ_LEN = 1000
    ENCODINGS = ['ascii','cp1252','mac_roman','utf_8','utf_16','utf_16_le',\
                 'utf_16_be','utf_32','utf_32_le','utf_32_be']

    #chars in the regular ascii printable set are BY FAR the most common
    #in most files written in English, so their presence suggests the file
    #was decoded correctly.
    nonsuspect_chars = string.printable

    #to be a list of 2 value tuples
    results = []

    for e in ENCODINGS:
        #some encodings will cause an exception with an incompatible file,
        #they are invalid encoding, so use try to exclude them from results[]
        try:
            with codecs.open(file_path, 'r', e) as f:

                #sample from the beginning of the file
                data = f.read(READ_LEN)

                nonsuspect_sum = 0

                #count the number of printable ascii chars in the
                #READ_LEN sized sample of the file
                for n in nonsuspect_chars:
                    nonsuspect_sum += data.count(n)

                #if there are more chars than READ_LEN
                #the encoding is wrong and bloating the data
                if nonsuspect_sum <= READ_LEN:
                    results.append([e, nonsuspect_sum])
        except:
            pass

    #sort results descending based on nonsuspect_sum portion of
    #tuple (itemgetter index 1).
    results = sorted(results, key=itemgetter(1), reverse=True)

    return results


def guess_encoding(file_path):
    """
    Stupid, simple, slow, brute and yet slightly accurate text file encoding guessing.
    Will return one likely text encoding, though there may be others just as likely.
    WARNING: DO NOT use if your file uses any significant number of characters
             outside the standard ASCII printable characters!
    WARNING: DO NOT use for critical applications, this code will fail you.
    """

    results = guess_encoding_debug(file_path)

    #return the encoding string (second 0 index) from the first
    #result in descending list of encodings (first 0 index)
    return results[0][0]
Run Code Online (Sandbox Code Playgroud)

我认为与chardet相比它会很慢,我并不是特别熟悉.也不太准确.它们的设计方式,任何使用重音符号,变音符号等的基于罗马字符的语言都不起作用,至少不行.很难知道它何时失败.但是,大多数英文文本(包括大多数编程代码)主要使用此代码所依赖的string.printable编写.

外部库可能是将来的选项,但是现在我想避免使用它们,因为:

  1. 该脚本将在具有各种版本的python的网络上和网络上的多台公司计算机上运行,​​因此复杂性越少越好.当我说"公司"时,我指的是社会科学家的小型非营利组织.
  2. 我负责从GPS数据处理中收集日志,但我不是系统管理员 - 她不是一个python程序员,我花的时间越少越好.
  3. 我公司通常可以安装的Python安装了一个GIS软件包,一般情况下保持不变.
  4. 我的要求不是太严格,我只想确定我感兴趣的文件,并使用其他方法将它们复制到存档.我没有读取内存的全部内容来操作,追加或重写内容.
  5. 看起来高级编程语言应该有某种方式来实现它自己.虽然"看起来"是任何努力的一个稳固的基石,我想尝试看看,如果我能得到它的工作.

Mar*_*cin 0

也许了解代码运行情况的最简单方法是采用其他现有库的测试套件,并使用它们作为基础来创建您自己的综合测试套件。您将知道您的代码是否适用于所有这些情况,并且您还可以测试您关心的所有情况。