zoukankan      html  css  js  c++  java
  • python3 open txt的UnicodeDecodeError: 'gbk' codec问题解决方案

    python3 open txt的UnicodeDecodeError: 'gbk' codec问题解决方案
    先直截了当给出解决方案,在程序开头加上:
    import _locale
    _locale._getdefaultlocale = (lambda *args: ['zh_CN', 'utf8'])
    12
    分析
    在Windows下经常用python open函数的人相信都遇到过UnicodeDecodeError: ‘gbk’ codec…这种编码问题。而且很多有经验的人应该知道解决方法是加上参数encoding=“utf-8”,因为"utf-8"是更通用的编码:
    open("test.txt",encoding="utf-8")
    然而这样的解决方法也有一些问题:

    有多个open的情况下,必须手动一个个添加参数,很麻烦
    更致命的是,当引用的第三方库中的open没有加上这个参数时,我们就几乎完全束手无策了(勇士可以尝试修改源码再重装)

    我正是因为碰到了第二种情况,于是下定决心找一个一劳永逸的方法解决问题,这就要对原理做一些深入探究。

    Python 和 encoding  相关的配置主要有下面几个:

    locale.getpreferredencoding() 这个用的是最广的。 这是 Python 在 open 文件时默认使用的 encoding
    sys.getdefaultencoding() 是 Python 进行 str/unicode(byte/str) 转换时默认使用的 encoding
    sys.getfilesystemencoding() 是用来 encoding 文件名的, 例如 open(b’balabala’)
    标准输入输出(print)的 encoding:
    4.1 若设置了 PYTHONIOENCODING 环境变量, 则以次变量为准
    4.2 标准输入输出是打到终端的话, 看终端的 locale 配置, 在 windows cmd 的代码页
    4.3 标准输入输出被重定向到文件的话, 则参照 1 , 用的是 ` locale.getpreferredencoding()
    ----出自:http://neue.v2ex.com/t/271999


    所以我们的目标是要修改环境配置,python解释器会取_getdefaultlocale()[1]作为默认编码类型。
    所以我们采用:
    import _locale
    _locale._getdefaultlocale = (lambda *args: ['zh_CN', 'utf8'])
    12
    重写函数后,会改变当前运行环境下的所有模块的默认编码。
    感谢在 https://juejin.im/post/5bd2b6d5e51d45735c3c0453 找到的解决方案
    —————————

    尝试用Python写一个Wordcloud的时候,出现了编码问题。
    照着网上某些博客的说法添添改改后,结果是变成了“UnicodeDecodeError: ‘utf-8’ codec can’t decode byte…”这个错误。
    捣鼓了一天啊,TXT(此处为本人现下内心表情)。最后,干脆写个最简单的文件读取,竟然还是报错。于是就考虑是不是txt的编码问题,因为读取的txt文件是在Mac上面新建的纯文本文件,一时没找到在哪里查看编码,最后拷贝到Windows系统上,查看了txt文件的编码,竟然是ASCII,不是我最爱的utf-8,Mac你辜负了我对你的一番信任啊!ε(┬┬﹏┬┬)3
    解决方法

    将txt文件的编码格式改为utf-8即可

    此外,在打开文件的时候,要加上第三个参数encoding=‘utf8’(没有横杠)。
    with open('./test3.txt','r',encoding='utf8') as fin:
        for line in fin.readlines():
            line = line.strip(' ')
    123
    下面附上第一次成功显示的词云的源码(参考网上他人的,注释很详细)
    import jieba
    import jieba.analyse
    from matplotlib import pyplot as plt
    from scipy.misc import imread
    from wordcloud import WordCloud,STOPWORDS,ImageColorGenerator
     
    # 1.读取数据
    with open("./test.txt","r",encoding="utf8") as f:
        text = f.read()
     
    # 2.基于 TextRank 算法的关键词抽取,top50
    keywords = jieba.analyse.textrank(text, topK=50, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'))
    file = ",".join(keywords)
     
    # 指定中文字体,不然中文显示框框
    font = r'./HYQiHei-25J.ttf'
    print(file)
    # 指定背景图,随意
    image = imread('cake.jpg')
    wc = WordCloud(
        font_path=font,
        background_color='white',#背景色
        mask=image,#背景图
        stopwords=STOPWORDS,#设置停用词
        max_words=100,#设置最大文字数
        max_font_size=100,#设置最大字体
        width=800,
        height=1000,
     
    )
     
    #生成词云
    image_colors = ImageColorGenerator(image)
    wc.generate(file)
     
    # 使用matplotlib,显示词云图
    plt.imshow(wc)  #显示词云图
    plt.axis('off') #关闭坐标轴
    plt.show()
    # 保存图片
    wc.to_file('news.png')
    ———————

    Python逐行读取文件内容

    代码来源: Python参考手册

    复制代码
    复制代码
    f = open("foo.txt")             # 返回一个文件对象
    line = f.readline() # 调用文件的 readline()方法
    while line:
    print line, # 后面跟 ',' 将忽略换行符
    # print(line, end = '')   # 在 Python 3中使用
    line = f.readline()

    f.close()
    复制代码
    复制代码

    也可以写成以下更简洁的形式

    for line in open("foo.txt"):
    print line,

    更详细的文件按行读取操作可以参考:http://www.cnblogs.com/xuxn/archive/2011/07/27/read-a-file-with-python.html

    复制代码
    复制代码
    1. 最基本的读文件方法:
    ?
    # File: readline-example-1.py

    file = open("sample.txt")

    while 1:
    line = file.readline()
    if not line:
    break
    pass # do something
      一行一行得从文件读数据,显然比较慢;不过很省内存。
      在我的机器上读10M的sample.txt文件,每秒大约读32000行
    2. 用fileinput模块
    ?
    # File: readline-example-2.py

    import fileinput

    for line in fileinput.input("sample.txt"):
    pass
      写法简单一些,不过测试以后发现每秒只能读13000行数据,效率比上一种方法慢了两倍多……
    3. 带缓存的文件读取
    ?
    # File: readline-example-3.py

    file = open("sample.txt")

    while 1:
    lines = file.readlines(100000)
    if not lines:
    break
    for line in lines:
    pass # do something
      这个方法真的更好吗?事实证明,用同样的数据测试,它每秒可以读96900行数据!效率是第一种方法的3倍,第二种方法的7倍!
    ————————————————————————————————————————————————————————————
      在Python 2.2以后,我们可以直接对一个file对象使用for循环读每行数据:
    ?
    # File: readline-example-5.py

    file = open("sample.txt")

    for line in file:
    pass # do something
      而在Python 2.1里,你只能用xreadlines迭代器来实现:
    ?
    # File: readline-example-4.py

    file = open("sample.txt")

    for line in file.xreadlines():
    pass # do something
    复制代码

    —————————

    python逐行读取文本

     

    一、使用open打开文件后一定要记得调用文件对象的close()方法。比如可以用try/finally语句来确保最后能关闭文件。

    二、需要导入import os

    三、下面是逐行读取文件内容的三种方法:

    1、第一种方法:

    [python] view plain copy

      

    复制代码
    f = open("foo.txt")               # 返回一个文件对象   
    line = f.readline()               # 调用文件的 readline()方法   
    while line:   
        print line,                   # 后面跟 ',' 将忽略换行符   
        #print(line, end = '')       # 在 Python 3 中使用   
        line = f.readline()   
       
    f.close()
    复制代码

    2、第二种方法:
      与第3种方法对比, 并非一次性将全部的文件内容载入到内存里,而是在迭代的时候,循环到哪一行才将哪一行读入内存。这里涉及到一个新的概念-迭代器。
      第二种方法是文本文件读取的最佳选择,它简单,且对任意大小的文件都有效,因为他不会一次性把整个文件都载入到内存里,相反第三种方法存在内存压力过大的问题。
    for line in open("foo.txt"):   
        print line,    

    3、第三种方法:
      
    f = open("c:\1.txt","r")   
    lines = f.readlines()      #读取全部内容 ,并以列表方式返回  
    for line in lines   
        print line 

    四、一次性读取整个文件内容:

     

      

    file_object = open('thefile.txt')  
    try:  
         all_the_text = file_object.read()  
    finally:  
         file_object.close()

    五、区别对待读取文本 和 二进制:

    1、如果是读取文本

      
        读文本文件  
        input = open('data', 'r')  
        #第二个参数默认为r  
        input = open('data')  

    2、如果是读取二进制
     
      
    input = open('data', 'rb')  

     读固定字节

     

    chunk = input.read(100)

    ———————

  • 相关阅读:
    Git ---游离状态下的commit 分支切换与找回,commit之后无法找到历史记录
    mybatis异常invalid comparison: java.util.Date and java.lang.String
    Spring的注解@Qualifier
    Spring @Bean注解的使用
    Java的IO系统
    linkin大话面向对象--GC和jar包
    linkin大话面向对象--闭包和回调
    linkin大话面向对象--内部类
    linkin大话面向对象--枚举
    linkin大话面向对象--接口
  • 原文地址:https://www.cnblogs.com/xinxihua/p/12609020.html
Copyright © 2011-2022 走看看