编写Python代码的多种工具介绍
前言
Python is getting more attention than usual this year, becoming one of the most popular programming languages in the world.
-- by Krzyszt
对于技术类文章,我一般都会联想到一些高大上的描述,或是一些人文故事。但是,对于Python这样的全民化编程语言,我觉得上面这句来自Krzyszt的口语化描述,就足够了。
Python是一种跨平台的编程语言,这就意味着它能够在所有主要的操作系统上,在所有安装了Python的现代计算机上,运行你编写的任何Python程序。今天文章里要给大家具体讲讲几款常见的工具,包括了Python自带的解释器、文本编辑器(Geany、Sublime Text)、主流IDE(PyCharm、Jupyter Notebook),以及如何使用公有云的计算资源在本地开发。
正文
Python自带的解释器
Python自带了一个在终端窗口中运行的解释器,你无需保存代码,支持直接运行整个程序,如下所示:
Geany
Geany是一款简单的文本编辑器,安装很容易,支持直接运行几乎所有的程序(不需要通过终端运行),支持使用颜色区分关键代码,突出代码语法。
我们可以在官网下载Geany软件:https://geany.org/。
安装完成后,首先在本地创建一个文件夹用于保存和运行代码,例如python_work文件夹。
创建一个新文件,并且通过“SAVE AS”保存到pytthon_word文件夹。
如果你已经安装了python,也就是说,如果能在系统中执行命令python,就无需配置Geany,如果不能执行顺利执行python命令就需要对Geany进行配置。
涉及到编码代码和运行代码的是“生成”按钮,如下图所示:
先来执行一个helloWolrld命令,如下图所示:
进一步解释“生成”下拉框所列的功能,我采用的是“阿姆斯特朗数”,即如果一个n位正整数等于其各位数字的n次方之和,则称该数为阿姆斯特朗数。 例如1^3 + 5^3 + 3^3 = 153。
代码如下:
# take input from the user
num = int(input("Enter a number: "))
# initialize sum
sum = 0
# find the sum of the cube of each digit
temp = num
while temp > 0:
digit = temp % 10
sum += digit ** 3
temp //= 10
# display the result
if num == sum:
print(num,"is an Armstrong number")
else:
print(num,"is not an Armstrong number")
“Compile”:编译代码,类似于执行了python -m py_compile helloWorld.py,生成.pyc文件。pyc是一种二进制文件,是由py文件经过编译后生成的文件,属于byte code。py文件变成pyc文件后,加载的速度有所提高,而且pyc是一种跨平台的字节码,是由python的虚拟机来执行的,这个是类似于JAVA或者.NET的虚拟机的概念。pyc的内容和python的版本相关,不同版本编译后的pyc文件不完全相同,例如v2.5编译的pyc文件在v2.4版本的 python上是无法执行的。
“Lint”:这个功能会对代码做静态检测,例如制表符、空格、变量命名等等是否符合要求,本案例中部分行只缩进了3个空格,第18行的“num,”后面缺少空格,报错如下所示:
代码改动完毕后就显示编译正常,如下图所示:
“生成目标文件”:运行”make current_file.o” 文件,好处是只会编译当前指定的文件,而不是整个项目。
“Execute”:实际上调用Python的终端编译器,如下图所示:
Geany的操作界面和编译器支持个性化配置,这里不逐一展开,你可以自己通过“编辑”-“首选项”尝试。
Sublime Text
和Geany类似,Sublime Text是一款简单的文本编辑器,能够直接运行几乎所有程序(无需通过终端),支持使用不同的颜色显示关键代码,突出代码语法。
Sublime Text的优点:
l 跨平台: Sublime Text为跨平台编辑器(在Linux、OS X和Windows下均可使用)。作为一个程序员,切换系统是常有的事情,为了减少重复学习,使用一个跨平台的编辑器是很有必要的;
l 可扩展: Sublime Text是可扩展的(Extensible),并包含大量实用插件,我们可以通过安装自己领域的插件来成倍提高工作效率;
l 互补: Sublime Text是命令行环境(CLI)和图形界面环境(GUI)下的最佳选择,同时使用两者会大大提高工作效率。
从使用的角度看,Sublime Text真的是针对程序员的工具,举一个例子,它的所有设置都是通过JSON配置文件完成的,支持你自己写配置文件的方式,感觉很好。
如上图所示,我在右边的可编程栏设置了字体大小,只要保存这个文档,Sublime Text已经打开的窗口会立即执行。
Sublime Text支持同时选择多个区域,然后同时进行编辑。Ctrl + D选择当前光标所在的词并高亮该词所有出现的位置,再次Ctrl + D选择该词出现的下一个位置,在多重选词的过程中,使用Ctrl + K进行跳过,使用Ctrl + U进行回退,使用Esc退出多重编辑。这样真是太棒了,写代码的人感觉自己的效率提升很多!
PyCharm
PyCharm是一个用于计算机编程的集成开发环境(IDE),主要用于Python语言开发,由捷克公司JetBrains开发,提供代码分析、图形化调试器,集成测试器、集成版本控制系统,并支持使用Django进行网页开发。PyCharm是一个跨平台开发环境,拥有Microsoft Windows、macOS和Linux版本。社区版在Apache许可证下发布,另外还有专业版在专用许可证下发布,其拥有许多额外功能。
PyCharm非常强大,几乎所有你自己可以想到的功能它都包含在内。我觉得判断一个IDE的生命力,我们应该重点看是否支持代码重构和利用周边生态(例如公有云计算资源),所以我这里重点介绍这两个特性。
首先讲代码重构。重构指的是使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构。我们通常所讲的代码重构,最常见是的有几类,例如重复代码(一个以上的地点看到相同的程序结构)、过长的类(一般不超过500行)、过长参数列(太长的参数列难以理解,太多的参数会造成前后不一致、不容易使用,而且一旦你需要更多数据,就不得不修改它)、发散式变化(如果某个类经常因为不同的原因在不同的方向上发生变化,那么此时也许将这个对象分成两个会更好,这么一来每个对象就可以只因为一种变化而需要修改)、冗余类,等等。
我们看一下具体的案例:
1、 常量和临时变量
假设如以下代码所示,你有一个字面数值, 带有特别含义. 创建一个常量, 根据其意义为它命名, 并将上述字面数值替换为这个常量。
def potential_energy(mass, height):
return mass * 9.81 * height
这里的9.81,改为GRAVITATIONAL_CONSTANT比较合适,
选Constant:
将代码改为如下图所示:
2、复杂表达式的简单化,例如以下代码:
if "MAC" in platform.upper() and "IE" in browser.upper() and was_initialized() and resize > 0:
#do something
我们可以把"MAC" in platform.upper()改为变量,也就是说以变量名称来解释表达式用途。
代码最终被重构如下图所示:
3、 抽象出可以复用的方法,减少业务方法的代码量。这里举一个最大公约数的示例代码
原始代码如下:
现在我们将最大公约数提取到单独的方法中,选中上面这张图中的10-14行代码,点击‘重构’按钮。
代码重构为:
变量factor通过使用 Inline variable重构来摆脱变量。我们选中变量factor,然后按Ctrl+Alt+N。所有检测到的factor变量都是内联的。
使用使用Change Signature更改参数名称。选中方法声明行,然后按Ctrl+F6。在打开的dialog box中,分别将参数denom和num重命名为x和y,然后单击图标节点upLevel以更改参数的顺序。
除了本地IDE工具功能以外,PyCharm能不能做得更好?我觉得就PyCharm自身来看,发展已经上了正规,我认为目前应该做的是生态的扩展,或者说联合。与谁联合?与公有云。如果能够做到在本地编码、利用公有云的计算资源进行调试,那相当于做到了云边协同。华为云ModelArts提供了插件,支持让本地的PyCharm与ModelArts结合在一起使用(详细的过程请参考文档:https://bbs.huaweicloud.com/blogs/160467)。
我们实际上只需要做三个步骤,即可支持本地的PyCharm与ModelArts平台结合使用:
1、 下载并安装插件;
2、 ModelArts网站申请秘钥;
3、 PyCharm填写秘钥键值对。
你把PyCharm想象成C/S设计模式的Client端,把ModelArts想象成Server端,就容易理解了。
我这里举一个实际的使用案例—手写字模型训练案例。
首先,下载手写字的数据集:https://modelarts-cnnorth1-market-dataset.obs.cn-north-1.myhuaweicloud.com/dataset-market/Mnist-Data-Set/archiver/Mnist-Data-Set.zip
登录华为云上传OBS:
创建两个文件夹,一个用于存放数据集,一个用于存放训练生成的日志(需要传回到PyCharm IDE并显示):
填写参数,可以参考ModelArts训练模型时填写的参数:
接着在PyCharm打开工程,点击“Run Training Job”:
上面的日志输出中,左下角是本地的输出,右下角是ModelArts返回的云端训练日志。
训练完成后,训练模型保存在OBS中 /工程名/output/V0006/。
Jupyter Notebook
在AI研究探索场景中,Jupyter 作为一个特殊的存在迅速成长为AI探索类场景开发的首选,能够在其各个阶段满足开发者诉求并覆盖这些关键点,以及支持在浏览器中使用的特点。
Jupyter 起始于 IPython 项目,IPython 最初是专注于 Python 的项目,但随着项目发展壮大,已经不仅仅局限于 Python 这一种编程语言了。按照Jupyter创始人的想法,最初的目标是做一个能直接支持Julia(Ju),Python(Py)以及R三种科学运算语言的交互式计算工具平台,所以将他命名为Ju-Py-te-R,发展到现在Jupyter已经成为一个几乎支持所有语言,能够把代码、计算输出、解释文档,多媒体资源整合在一起的多功能科学运算平台。
这里需要提到的另外一个概念就是“文学编程”,文学编程是一种由Donald Knuth提出的编程范式。这种范式提供了用自然语言来解释程序逻辑的机会。简单来说,文学编程的读者不是机器,而是人。 从写出让机器读懂的代码,过渡到向人们解说如何让机器实现我们的想法,其中除了代码,更多的是叙述性的文字、图表等内容。 文学编程中间穿插着宏片段和传统的源代码,从中可以生成可编译的源代码。
作为第一个贯穿整个科学计算研究的生命周期工具平台,可以将可以分解为,如果我们将科学计算研究全生命周期分解为,个人探索,协作与分享,生产化运行环境,发表与教学,Notebook都可以在这些阶段中满足科研工作的需求。
Jupyter有没有缺点?有的。如果你追求的是产品化代码开发,例如代码格式、依赖管理、产品打包、单元测试等等功能在IDE中是没有很好的支持,当前有一些插件可以做,但是相比重型IDE,功能还是比较弱。此外,Jupyter定义为研究类调试环境,一方面对于分布式的任务当前推荐都是通过单机多进程的方式进行模拟,真实到有多节点拓扑信息的部分在Jupyter中不容易实现,另外一方面,Jupyter的架构并不适合跑非常重量级的作业。对于真实软件产品开发的诉求,还是需要在IDE中进行工程化代码开发,并配搭测试逻辑,将任务部署在集群中进行运行。
我们具体看看Jupyter如何工作的?首先在公有云上创建一个Notebook,点击“打开”按钮,如下图所示:
选择基于那个计算引擎(例如TensorFlow-1.8),如下图所示:
输出代码片段,在第一段代码中由于已经请求了用户输入,所以需要我们输入一个数字,只要是正常的整形数字,不会报错,如下图所示:
后记
这篇文章的后记比较难写,因为工具总是在不断发展的,我们很难预料未来某一个工具的发展方向和趋势,但是,永恒的定律是工具一定是为开发者服务的,一定是越来越简单。
编辑器和IDE根本是面向两种不同使用场景的工具:
l 编辑器面向无语义的纯文本,不涉及领域逻辑,因此速度快体积小,适合编写单独的配置文件和动态语言脚本(Shell、Python和Ruby等);
l IDE面向有语义的代码,会涉及到大量领域逻辑,因此速度偏慢体积庞大,适合编写静态语言项目(Java、C++和C#等)。
个人认为应当使用正确的工具去做有价值的事情,并把效率最大化,所以我会用IntelliJ IDEA编写Java项目,用Vim编写Shell,用Sublime Text编写JavaScript/HTML/Python,用Visual Studio编写C#。
工具再好用,代码还是你自己写的,因此本文的最后,我引用Python之禅(在Python交互式解释器中输 入import this就会显示Tim Peters的The Zen of python):
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly. 优美优于丑陋(以编写优美的代码为目标)
Explicit is better than implicit. 明了优于隐晦(优美的代码应当是简洁明了的)
Simple is better than complex. 简单优于复杂(避免存在过多的复杂内部实现)
Complex is better than complicated. 复杂优于凌乱(保持接口简洁)
Flat is better than nested. 扁平优于嵌套(避免多层嵌套)
Sparse is better than dense. 间隔胜于紧凑(保持适当的间隔,不要奢望一行代码解决问题)
Readability counts. 可读性很重要(保持并不断提提升代码的可阅读感)
Special cases aren't special enough to break the rules. 即使实用比纯粹更优
Although practicality beats purity. 特例亦不可违背原则
Errors should never pass silently. 错误绝不能悄悄忽略
Unless explicitly silenced. 除非它明确需要如此
In the face of ambiguity, refuse the temptation to guess. 面对不确定性拒绝妄加猜测
There should be one-- and preferably only one --obvious way to do it. 任何问题应有一种且最好只有一种显而易见的解决方法
Although that way may not be obvious at first unless you're Dutch. 尽管这方法一开始并非如此直观除非你是荷兰人(指的是Python之父荷兰人Guido van Rossum)
Now is better than never. 做优于不做
Although never is often better than *right* now. 然而不假思索还不如不做
If the implementation is hard to explain, it's a bad idea. 很难解释的,必然是坏方法
If the implementation is easy to explain, it may be a good idea. 很好解释的,可能是好方法
Namespaces are one honking great idea -- let's do more of those! 提倡使用命名空间
上面这些准备,并不单单适用于Python,编程语言体系都适用。
作者:周明耀,九三学社社员,2004年毕业于浙江大学,工学硕士。现任华为云AI产品研发总监,著有《大话Java性能优化》、《深入理解JVM&G1 GC》、《技术领导力-如何带领一支软件研发团队》、《程序员炼成记》等。职业生涯从软件工程师起步,后转为分布式技术工程师、大数据技术工程师,2016年开始接触AI技术。微信号michael_tec。
- 点赞
- 收藏
- 关注作者
评论(0)