编写更好Python程序的5个技巧

更新时间:2017-10-10 10:56:23点击次数:420次


如果你是Python程序员,你一定积累了不少的编程技巧,下文中的这些技巧,你掌握了么?


我写Python已经有一段时间了,当我回顾起一些较老的代码时,我有时会感到一些畏缩。例如,当我刚开始编程的时候,我用python编写了这个Sudoku 游戏(在GitHub上可以获得)。我当时认为这是我最好的作品之一。事实证明,我甚至不能克隆并运行它,因为我没有添加一个setup.py或 requirements.txt文件,这是我今天绝不会犯的错误!

这让我反思了多年来Python代码的质量是如何变化的。它确实变得更干净,更健壮,更易于阅读。但是是什么使它成为这样的呢?

在这篇文章中,我将探讨一下对于编写python代码方式所做的一些改变——不管是大的还是小的。我这样做是希望能够帮助你提高Python代码的质量。其中一些技术甚至可能适用于其他语言和技术。

1.让你的代码成为可PIP安装(PIP-installable)包

当你拿到一个新的Python包时,开始使用它还是比较容易的,你所做的只需输入“pip install”,加上包名或者路径,然后运行它。

有很多种方法来完成这项工作,我的方法是为我的项目创建一个setup.py文件。

假定在 “flask_example.py”中有一个简单的Flask程序:

from flask import Flask
app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!' def main(): app.run() if __name__ == ‘__main__’:
    main()

我们可以将其转换为可安装的Python包,首先将其移动到一个单独的文件夹中(我们将其称为“flask_example/”。然后,我们可以在根项目文件夹中创建setup.py文件,该文件看起来是这样的:

from distutils.core import setup

setup(
    name='flask_example',
    version='1.0',
    description='Hello, World! in flask.',
    packages=['flask_example'],
    install_requires=[ 'Flask==0.12.2' ],
    entry_points = { 'console_scripts': 'runserver=flask_example.flask_example:main' }
)

这样做有一些优点。首先,你现在可以使用“pip install -e .”本地安装你的应用。这使得开发人员可以更容易地克隆和安装你的项目。因为setup.py文件将处理所有繁重的工作。

其次,setup.py还可以处理依赖管理工作。 install_requires变量允许你定义使用的包和特定的版本。如果你不确定所使用的包和版本,你可以运行“pip freeze”来查看这些信息。

最后,这样还允许你为你的包定义入口,这只需在命令行上输入“runserver”来执行代码。

2.在预提交(Pre-Commit )钩子上整理(Lint)代码

使用linter可以在代码中解决很多问题。PyLint是Python的一个很好的linter,如果你使用像Git这样的版本控制系统,那么你可以在提交代码前,让Git通过一个linter运行你的代码,。

要做到这一点,需要安装PyLint包。

pip install pylint

然后,将以下代码添加到.git/hooks/pre-commit中。如果你已经有了一个预提交钩子,那么简单地将pylint命令附加到文件的末尾。

#!/bin/sh pylint <your_package_name>

这可以在提交到Git库前就捕捉所有类型的错误。你可以对代码中的语法错误以及其他的一个良好的linter 可以捕捉到的错误说再见了,

3.使用绝对导入还是相对导入

在python中,导入命令语句中(如 from . import module_name)很少使用相对模块路径。如果你已经经历了为你的项目创建setup.py文件(或者类似的机制)的过程, 你可以简单地通过它们的完整模块路径来引用子模块。

在Python 风格指南PEP-8中推荐使用绝对导入。这是因为在它们的名字里包含了更多的信息,而且根据 Python Softwa的说法,这样也有“更好的表现”。

我深有体会的是使用相对导入很快会成为一场噩梦。当你开始编程的时候,万事皆好,但是,一旦你可以移动模块或者进行重大重构的时候,这会让你感到头疼了。

4.上下文管理器

无论你何时打开一个文件、流或者是连接器的时候,你都会和上下文管理器打交道。上下文管理器的重要性在于:如果使用恰当,它们可以处理诸如关闭文件时抛出异常这样的问题。为了做到这一点,只需使用关键字。 
下面是大多数Python初级程序员可能写入文件的语句。

f = open(‘newfile.txt’, ‘w’)
f.write(‘Hello, World!’)
f.close()

这相当简单,但是想象一下如下场景:你正在将成千上万行代码写入一个文件。在某个时候,出现了一个异常。因为异常的产生,你的文件没有正确地关闭,那些所有的你认为已经正确写入文件的数据都损坏或丢失了。

不过,不要担心,通过一些简单的重构,我们可以确保文件正确地关闭,即使遇到异常。我们可以这样做,如下所示。

with open(‘file’, ‘w’) as file: file.write(‘Hello, World!’)

太棒了!真的很简单。此外,代码看起来更清爽,而且更简洁。你还可以使用单个“with”语句打开多个上下文管理器,从而消除了嵌套“with”语句的需要。

with open(‘file1’, ‘w’) as f1, open(‘file2’, ‘w’) as f2:
    f1.write(‘Hello’)
    f2.write(‘World’)

5.使用良好命名(Well-Named)的函数和变量

在Python,尤其是非强类型语言中,很容易不清楚什么样的函数要返回什么值。特别是当你只是某个库中一些函数的使用者时。如果你可以为开发人员节省在文档中查找函数的5分钟时间,这实际上是一个非常有价值的改进。但是我们该怎么做呢?如何做一些简单的如更改变量名字这样事情,来节省开发时间?

在命名函数或变量时,我喜欢考虑三件主要的事情:

  1. 函数和变量要做什么
  2. 任何与函数或变量相关的单元
  3. 函数或变量的数据类型

例如,如果我想创建一个函数来计算矩形的面积,我可能会将其命名为“calc_rect_area”。但是这不会让用户了解更多的信息。它会返回这个值?或者它会存储在什么位置?这个值单位是英尺还是米?

为了提高这个函数的名字,我会把其改为 “get_rect_area_sq_ft”。这就让用户清楚的了解函数的功能和返回值。也让用户明白面积的单位是平方英尺。

如果你可以通过给函数和变量恰当的命名来给开发人员处处节约时间,不仅提高了开发效率,也使他们更乐意使用你的代码。

结论

在作为Python程序员的这些年里,我发现这些技巧还是很有帮助的。有些是我自己摸索出来的,有些是别人教我的。我希望这个列表能够帮助您编写更好的Python代码。


  • 项目经理 点击这里给我发消息
  • 项目经理 点击这里给我发消息
  • 项目经理 点击这里给我发消息
  • 项目经理 点击这里给我发消息