记录一下 Python 源文件一行字符过长从而造成的问题.
首先声明下, 这个问题不是我遇到的, 是在刷华蟒的时候看到的一个帖子, 帖子地址在这儿, 有兴趣的可以看看
起因是帖主在源文件中定义了一个超长的集合, 该集合如下

e = {'合作社', '经济', '财税', '账', '旅行社', '维修', '押运', '管理咨询', '基业', '养生', '雕塑', '上海警', '首饰', '商行', '电脑', '人才网', '素食', '日用制品', '铝制品', '百货', '银行', '产业园', '商学院', '驾驶培训', '生活', '潜水服务', '电视台', '贸易', '副食', '铝业', '风投', '财经', '警察协会', '试验', '展会', '金融', '陶艺', '营业部', '眼镜', '物业', '飞手', '实验', '幼教', '超市', '植保机用户', '农服', '教育', '会展', '销售', '果业', '保险', '生态园', '企业管理', '印刷', '电力局', '传播', '贷', '拆迁', '装饰', '养老', '人寿', '生活馆', '财务', '餐饮', '咨询服务', '出品', '个体', '办公', '自由职业', '动漫', '中央', '商务', '老年人', '农资', '新华社', '博览会', '新华网', '珠宝', '航展', '工贸', '专利', '市政', '体验', '网吧', '水敏纸检测喷潵效果', '破产', '大申网', '促进会', '酒业', '烟草', '家政', '威海警', '自来水', '代理', '售货', '创意', '基金', '进出口', '融资', '银联', '制衣', '暂无', '成人', '影视', 'VC', '英烈', '风水', '营销', '摄影', '小公司', '广告', '国贸', '服饰', '招聘', '创业', '新闻', '兽药', '体育节', '母婴', '还没定', '农村信用合作社', '人力', '国际货运', '职业技能', '知识产权', '酒店', '理发', '中财', '经营', '体检', '证券', '宾馆', '科贸', '经销', '个人', '报社', '宇辰世纪', '旅游', '展览', '演出', '宇辰网', '出版社', '媒体', '认证咨询', '电子商务', '孵化', '化妆', '职业学院', '拍卖', '葬', '杂货', '五金', '传媒', '配件店', '应用服务', '妈妈', '助理', '新华书店', '卫视', '路店', '驾驶员培训', '道具', '世强', '小卖部', '待业', '医院', '外贸转卖', '培训', '会所', '趣味', '门诊', '资产管理', '日用品', '……', '资本', '礼仪', '商贸', '供电局', '管理局', '文化', '用户', '协会', '政府', '商旅', '展览会', '个体户', '食物', '小学', '云知声', '地铁店', '信用社', 'CCTV', '园林', '墓', '学校', '杂志', '区块链', '商店', '俱乐部', '财富', '食品', '股权', '便利店', '投资', '机关', '租赁', '茶业', '农夫', '种业', '职业技术学院', '连锁', '政界', '金属', '电商', '政治', 'Suffice Ind. Tech. Ltd.', '装潢', '犬业', '城管', '纤维', '新媒体', '交易中心', '经贸', '分店', '报纸', '#NAME?', '质量检测', '社区', '资讯', '劳务', '担保'}print(e)
复制代码

然后直接运行该源文件, 就得到了以下报错:

python test.py File "test.py", line 3
SyntaxError: Non-UTF-8 code starting with '\xe7' in file test.py on line 3, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
复制代码

然后我尝试着加上声明源文件编码的 Shebang # -*- coding: utf8 -*- 就好使了.

这就很有意思了, 为什么呢? 抱着有没有大神的回复继续往下翻, 果然, 大腿出现了.

研究了一下 Python3.6.6 的源码,我认为是Python在解析源码时出问题了,涉及到的代码在decoding_fgets。

Python 解析源码时通过 decoding_fgets 读取一行源码至 buffer 中,decoding_fgets 可能使用两种方式从文件中读取源码:

1.假如在文件开头指定了文件编码或者文件包含 utf-8 BOM,则使用 io.open以该编码打开文件,使用 readline 方法读取一行源码。

2.假如没有指定编码,则使用 Py_UniversalNewlineFgets 读取一行源码。

使用方式1读取源码没有任何问题。
当使用方式2时,Python 会通过valid_utf8检查读取到的代码的编码是不是合法的 utf8,一般情况下这也没有问题,但是 buffer 的初始长度是1024字节,如果一行代码太长(超过1023字节),则需要分多次读取,buffer 长度每次递增1024。运气差的情况下,分次读取时正好把一个汉字的字节给切分开,这就会导致编码错误。

然后我顺着大腿的思路给代码 Format 了一下, 果然可行...

e = {'合作社', '经济', '财税', '账', '旅行社', '维修', '押运', '管理咨询', '基业', '养生', '雕塑', '上海警', '首饰', '商行', '电脑', '人才网', '素食', '日用制品','铝制品', '百货', '银行', '产业园', '商学院', '驾驶培训', '生活', '潜水服务', '电视台', '贸易', '副食', '铝业', '风投', '财经', '警察协会', '试验', '展会','金融', '陶艺', '营业部', '眼镜', '物业', '飞手', '实验', '幼教', '超市', '植保机用户', '农服', '教育', '会展', '销售', '果业', '保险', '生态园', '企业管理','印刷', '电力局', '传播', '贷', '拆迁', '装饰', '养老', '人寿', '生活馆', '财务', '餐饮', '咨询服务', '出品', '个体', '办公', '自由职业', '动漫', '中央','商务', '老年人', '农资', '新华社', '博览会', '新华网', '珠宝', '航展', '工贸', '专利', '市政', '体验', '网吧', '水敏纸检测喷潵效果', '破产', '大申网', '促进会','酒业', '烟草', '家政', '威海警', '自来水', '代理', '售货', '创意', '基金', '进出口', '融资', '银联', '制衣', '暂无', '成人', '影视', 'VC', '英烈','风水', '营销', '摄影', '小公司', '广告', '国贸', '服饰', '招聘', '创业', '新闻', '兽药', '体育节', '母婴', '还没定', '农村信用合作社', '人力', '国际货运','职业技能', '知识产权', '酒店', '理发', '中财', '经营', '体检', '证券', '宾馆', '科贸', '经销', '个人', '报社', '宇辰世纪', '旅游', '展览', '演出', '宇辰网','出版社', '媒体', '认证咨询', '电子商务', '孵化', '化妆', '职业学院', '拍卖', '葬', '杂货', '五金', '传媒', '配件店', '应用服务', '妈妈', '助理', '新华书店','卫视', '路店', '驾驶员培训', '道具', '世强', '小卖部', '待业', '医院', '外贸转卖', '培训', '会所', '趣味', '门诊', '资产管理', '日用品', '……', '资本','礼仪', '商贸', '供电局', '管理局', '文化', '用户', '协会', '政府', '商旅', '展览会', '个体户', '食物', '小学', '云知声', '地铁店', '信用社', 'CCTV','园林', '墓', '学校', '杂志', '区块链', '商店', '俱乐部', '财富', '食品', '股权', '便利店', '投资', '机关', '租赁', '茶业', '农夫', '种业', '职业技术学院','连锁', '政界', '金属', '电商', '政治', 'Suffice Ind. Tech. Ltd.', '装潢', '犬业', '城管', '纤维', '新媒体', '交易中心', '经贸', '分店', '报纸','#NAME?', '质量检测', '社区', '资讯', '劳务', '担保'}print(e)
复制代码

这个时候加不加声明源文件编码的 Shebang 都不会报错

当然, 如果按照 PEP8 规范老老实实写上 声明源文件编码的 Shebang(即使是 Python3 也应该如此), 代码规范按照 PEP8 限制下最大长度就不会出现这个问题. 但是, 从Python解释器读取源文件的方面来说, 确实是涨芝士了, 原来是CPython读取源文件是这么读取的.

转载于:https://juejin.im/post/5bf91bbce51d4561a86c04da

Python源文件一行字符过长造成的问题相关推荐

  1. Python 统计一行字符中单词的个数_Python 经典练习题-015

    题目:输入一行字符,分别统计出其中英文字母.空格.数字和其它字符的个数. 题目分析:要想统计这些类型的数量,首先必须确定字符串中每一个元素是什么类型.你可能想到了用 Python 内置的isdigit ...

  2. python sql语句换行_python一行sql太长折成多行并且有多个参数的方法

    python一行sql太长折成多行并且有多个参数 sql语句本身就支持多行, 你可以用两种方法断行 注意: 第一种会带入换行符(\n), 第二种只是一行 a='''xxxx本身也可以作为注释使用xxx ...

  3. python接收输入的一行字符只统计数字的个数,Python(统计字符),python实例,输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数...

    Python(统计字符),python实例,输入一行字符,分别统计出其中英文字母.空格.数字和其它字符的个数 题目:输入一行字符,分别统计出其中英文字母.空格.数字和其它字符的个数. 程序分析:利用 ...

  4. ACMNO.27 Python的两行代码解决 C语言-字符逆序 写一函数。使输入的一个字符串按反序存放,在主函数中输入输出反序后的字符串。 输入 一行字符 输出 逆序后的字符串

    题目描述 写一函数,使输入的一个字符串按反序存放,在主函数中输入输出反序后的字符串. 输入 一行字符 输出 逆序后的字符串 样例输入 123456abcdef 样例输出 fedcba654321 来源 ...

  5. python 取一个字前的文本的_python删除某一行字符前面的内容

    python怎么把字符串第一个字符去掉年轻总是容易犯错的,尤其是拿爱和岁月比漫长. 比如小编输入C69.6 怎样保留69.6而去掉"C" 编写一个python程序,从非空字符串中删 ...

  6. python找到一行单词中最长的_python - 查找.txt文件中最长的单词,不带标点符号 - SO中文参考 - www.soinside.com...

    我正在做Python文件I / O练习,尽管在尝试查找.txt文件每一行中最长的单词的练习上取得了巨大进步,但我无法摆脱标点符号.] > 这是我的代码:with open("origi ...

  7. (C语言)输入一行字符,将此字符串中最长的单词输出。

    输入一行字符,将此字符串中最长的单词输出. #include<stdio.h> #include<string.h> int main() {char a[100], b[10 ...

  8. 萌新的Python练习菜鸟100例(十七)输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。

    题目: 输入一行字符,分别统计出其中英文字母.空格.数字和其它字符的个数. 分析: · string模块的使用: 字符串实现了所有一般序列的操作,还额外提供了以下列出的一些附加方法. 字符串还支持两种 ...

  9. python练习17:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。

    #输入一行字符,分别统计出其中英文字母.空格.数字和其它字符的个数. #思路:找到目标(正则),计数() from typing import Counter import re input='ASD ...

最新文章

  1. 聚合支付设计方案,该如何设计?
  2. android.database.cursorindexoutofboundsexception错误解决 及获取某行某列信息
  3. c语言里变量列表,嵌入式C语言里的土豪们之变量类型
  4. 前端教程分享:十行代码实现title滚动显示
  5. 知己知彼 防范攻击:网络攻击步骤与黑客攻击原理
  6. 温度补偿计算公式_钢材的基本计算公式(下)
  7. Git(4)-- 如何退出 git log 和 git commit 状态
  8. pbs 作业管理命令
  9. opencv图像分析与处理(6)- 二维取样定理与二维傅里叶变换
  10. MySQL基础3-SQL语言
  11. html显示ftp资料,获取FTP信息及使用方法
  12. Spring Cloud 入门手册
  13. cocos2d音效设置
  14. java实现office转pdf文件
  15. 12306网站专家:拟采取办法应对抢票软件
  16. 中国海外文物拍卖天价
  17. 下载Python编辑器Thonny教程
  18. textarea剩余可输入字数
  19. 微服务学习总结5(Ocelot+Polly+Consul)
  20. visio中如何画线条或箭头

热门文章

  1. whmcs对接ep插件_WHMCS完整对接文曦EP主机分销教程【EP.CITY618.CN】
  2. HBase高级配置跟调整(1)
  3. Android面试-LaunchMode及Task工作模式(扔物线笔记)
  4. CV codes代码分类整理合集
  5. 内容无错误,但运行不出来
  6. 子弹连发以及后坐力动画制作
  7. QA:xilinx系列verilog版出版事宜
  8. 为什么我从阿里巴巴辞职选择自由职业?
  9. ICT:IT与CT的融合之路
  10. JavaScript day10