Python 坑爹之 代码缩进
建议:统一使用空格!!!!!!!!!不要Tab
Python代码缩进
这两天python-cn邮件列表有一条thread发展的特别长,题目是《python的代码缩进真是坑爹》(地址),楼主在一台电脑上用KOMODO写的代码到另一台电脑上就不能运行了,调试后才发现是代码缩进的问题,为此楼主表示“真是火大”!而之后的回复,可想而知,批判楼主、教育楼主、鄙视楼主等的人绝不是少数(毕竟是python邮件列表,都是python开发者、爱好者嘛)。
要求严格的代码缩进是python语法的一大特色,就像C语言家族(C、C++、Java、C#等等)中的花括号一样重要,在大多数场合还有必要。在很多代码规范里面也都有要求代码书写按照一定的规则进行换行和代码缩进,但是这些要求只是纯粹是方便人(程序员)来阅读、使用或修改的,对于编译器或者解释器而言,完全是视而不见的。但是对Python解释器而言,每行代码前的缩进都有语法和逻辑上的意义。Python的这个特性,也经常在Python使用者和非Python使用者中引起争论。
Python的代码缩进之起源,有人说事继承于ABC(没听过但感觉很古老的语言),有人说是避免花括号,我猜可能是python发明者一时心血来潮的决定,大概也只有他能解释这个问题。不管怎样,作为发展了十余年的一名语言,这条语法规则已经不大可能改变了。
实际上,严格要求(强制)的代码缩进,就像一把双刃剑,有好处也有坏处。好处显而易见,在严格要求的代码缩进之下,代码非常整齐规范,赏心悦目,提高了可读性,在一定程度上也提高了可维护性。有人说,这种约束,对团队开发非常有利,当然,也不见得,这就要看强制代码缩进的坏处。Python严格的代码缩进,对于从其他语言转过来的人(现在计算机和相关专业第一门语言一般都是C/C++或Java吧,他们的语法风格基本是一直的),可能要适应一段时间。代码缩进十分严格,如果不按规律办事,不小心的话就会出现语法错误,比如unexpected indent之类的。甚至有时也会出现逻辑错误。
在实际情况中,由于代码缩进而出现语法错误或逻辑错误,在我看来有这两种主要情况,一是混用tab和空格缩进,二是编辑器对缩进的处理各异。这里给出一个例子,代码是这样的:

图中使用的Notepad++编辑器,箭头代表一个tab,点表示一个空格,默认情况下不会显示箭头和点,需要专门在视图-显示符号-显示空格和制表符 中启用这个功能。如果没有箭头和点,一般认为执行结果应该是显示a,实际是显示a、c,原因很简单,1个tab,python会认为是8个空格。如果换成其他编辑器,可能print 'c'就不会和print 'b'同列显示了。对于同一个文本,简单的修改,不同编辑器做保存,也可能导致缩进出现不同。
我觉得为了避免因代码缩进而产生不必要的麻烦,写python代码应该,使用唯一的缩进方式(要么tab,要么空格),使用固定和统一的编辑器,此外,还应该利用好编辑器的一些特性。对于notepad++而言,除了上面所说的显示空格和制表符外,还有两个特性可以使用:一是,编辑菜单下的blank operation有两个选项tab to space和space to tab,如果对上图的那段代码做tab to space,代码列对齐基本不变,箭头都变成点,但是执行结果是a;二是,在 设置-首选项-语言下可以选上“以空格代替”,这样以后每次按tab键都会自动转换为空格。
其他的编辑器,也有对应的一些处理技巧,比如,列表中有人提出,对VIM可以这样设置:
set list
set listchars=tab:\|\ ,trail:-,nbsp:_
更多的编辑器特性,google上面应该还有很多,这里就不赘述了。
处理好代码缩进的问题,应该算是python的基本功吧。
Python脚本运行出现语法错误:IndentationError: unindent does not match any outer indentation level
【问题】
一个python脚本,本来都运行好好的,然后写了几行代码,而且也都确保每行都对齐了,但是运行的时候,却出现语法错误:
IndentationError: unindent does not match any outer indentation level
【解决过程】
1.对于此错误,最常见的原因是,的确没有对齐。但是我根据错误提示的行数,去代码中看了下,没啥问题啊。
都是用TAB键,对齐好了的,没有不对齐的行数啊。
2.以为是前面的注释的内容影响后面的语句的语法了,所以把前面的注释也删除了。
结果还是此语法错误。
3.后来折腾了半天,突然想到了,把当前python脚本的所有字符都显示出来看看有没有啥特殊的字符。
当前用的文本编辑器Notepad++,好像有个设置,可以显示所有的字符的。
找到了,在:
视图 -> 显示符号 -> 显示空格与制表符

然后就看出问题来了:
原来错误的行数是1580行:

但是源码的1580行的对齐用的是点点点的空格,是和前面的几行的对齐所用的箭头表示的TAB键,是不匹配的,即代码的对齐,混用了TAB键和空格:

而新的Python语法,是不支持的代码对齐中,混用TAB和空格的。所以出现上述错误提示了。
知道原因了,解决起来就简单了:
去把对应的TAB,都改为空格,统一一下对齐的风格,即可。
在Notepad++中,去:
设置->首选项:

语言->以空格取代(TAB键):

即可实现,对于以后每次的TAB输入,都自动转换为4个空格。
【总结】
Python中遇到IndentationError,以后第一时间就要想到,是不是由于TAB键和空格混搭使用了。
估计很多人也都是此类原因导致的。记得统一一下就好。
Python 坑爹之 代码缩进的更多相关文章
- Python代码缩进与测试模块
一.Python代码缩进 Python 函数没有明显的 begin 和 end ,没有标明函数的开始和结束的花括号.唯一的分隔符是一个冒号 ( : ),接着代码本身是缩进的. 例如:缩进 bui ...
- python的代码缩进和冒号
一般语言一样采用{}或者begin...end分隔代码块,而是python中,采用代码缩进和冒号来区分代码之间的层次. 缩进的空白数量是可变的,但是所有代码块语句必须包含相同的缩进空白数量,这个必须严 ...
- python基础(代码规范、命名规范、代码缩进、注释)
代码规范 PEP8(python增强建议书第8版) 每个import语句只导入一个模块 不要在行尾添加分号";" 建议每行不超过80个字符 超出部分可以用()来进行换行例如: ...
- 第四章 Python外壳:代码结构
Python的独特语法: 不使用分号结束语句,而是回车: 通过代码缩进来区分代码块: if.while.for等,都不用括号,但不能没有冒号(:). 如何将一行命令分为多行? >>> ...
- python的PEP8 代码风格指南
PEP8 代码风格指南 这篇文章原文实际上来自于这里:https://www.python.org/dev/peps/pep-0008/ 知识点 代码排版 字符串引号 表达式和语句中的空格 注释 版本 ...
- python开发_python代码风格(coding style)
我们要做python开发,我想python中的代码风格我们有必要了解一下 这样对我们自己和他们所编写的代码都有好处的. 下面是8点重要代码风格注意事项: ONE : Use 4-space inden ...
- Vim代码缩进设置
前段配置VPS,无奈只能使用Vim编辑Python代码,比较头疼的没法设置自动缩进,所以搜索了相关的配置,特记录如下. 将以下的设置加入到~/etc/vim/.vimrc中: set sw=4 set ...
- XCODE多行代码缩进快捷键
转自:http://xiagudao.com/xcode多行代码缩进快捷键 在XCODE中无法使用TAB键对多行代码进行缩进.想多行缩进,选中需要缩进的代码使用快捷键command(花键)+] 即可右 ...
- Python第一行代码
Python版本:Python 3.6.1 0x01 命令行交互 在交互式环境的提示符>>>下,直接输入代码,按回车,就可以立刻得到代码执行结果.现在,试试输入100+200,看看计 ...
随机推荐
- UVA 11636 - Hello World! 水
水题,贪心,dp都随意 /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,ple ...
- for
1,cout在显示bool值之前将他们转换为int,但cout.setf(ios::boolalpha)函数调用设置了一个标记,标记命令cout显示true 和 false 而不是 1 和0;
- Gson 基础教程 —— 自定义类型适配器(TypeAdapter)
1,实现一个类型适配器(TypeAdapter) 自定义类型适配器需要实现两个接口: JsonSerializer<T> JsonDeserializer<T> 和两个方法: ...
- springboot中的406(Not Acceptable)错误
今天遇到一个很奇怪的问题,我用springboot开发时,用ajax请求服务想返回json数据,页面总是报406错误,这个错误使我郁闷了很久,原来我的后台服务是这么写的 看到没value的后面有个.h ...
- Apache HttpComponents Client 4.0快速入门/升级-2.POST方法访问网页
Apache HttpComponents Client 4.0已经发布多时,httpclient项目从commons子项目挪到了HttpComponents子项目下,httpclient3.1和 h ...
- Android学习之路——Android四大组件之activity(二)数据的传递
上一篇讲了activity的创建和启动,这一篇,我们来讲讲activity的数据传递 activity之间的数据传递,这里主要介绍的是activity之间简单数据的传递,直接用bundle传递基本数据 ...
- C++ operator关键字(重载操作符)(转)
operator是C++的关键字,它和运算符一起使用,表示一个运算符函数,理解时应将operator=整体上视为一个函数名. 这是C++扩展运算符功能的方法,虽然样子古怪,但也可以理解:一方面要使运算 ...
- Linux学习笔记01:Linux下的drwxr-xr-x
1. drwxr-xr-x 第1字母:表示文件类型 d ------- 表示文件目录(directory) - ------- 表示二进制文件 l ------ ...
- Java程序性能分析工具Java VisualVM(Visual GC)—程序员必备利器
VisualVM 是一款免费的\集成了多个JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优.这些功能包括生成和分析海量数据.跟踪内存泄漏.监控垃圾回收 ...
- JQuery 获取checkbox被选中的值
html代码 <ul id="dxbox"> <li><input type=" ...