python代码编写工具
Despite its
尽管它
downsides, Python remains the king of today’s programming world. Its versatility, beginner-friendliness, and huge community are just a few factors that have contributed to its tremendous 不利之处是 ,Python仍然是当今编程世界的王者。 它的多功能性,初学者友好性和庞大的社区只是在过去几年中为其巨大 growth over the last few years. And even though newer languages like 发展做出贡献的几个因素。 而且,即使诸如 Rust, Rust , Go, and Go和 Julia are gaining traction, Python’s reign will likely carry on over the next few years. Julia之类的较新语言越来越受欢迎,Python的统治也可能会在未来几年继续。Whether you’re a beginner or a seasoned engineer, you’re probably dealing with Python on a regular basis. In this context, it makes perfect sense to up your game a little bit.
无论您是初学者还是经验丰富的工程师,您都可能会定期与Python打交道。 在这种情况下,略微提高游戏水平是很有意义的。
Developers don’t code one thing and then leave it untouched for years to come. Therefore, good code isn’t only about speed and efficiency. It’s also about readability and maintainability.
开发人员不编写任何东西,然后在以后的几年中保持不变。 因此,好的代码不仅仅是速度和效率。 它还与可读性和可维护性有关。
Like with everything in life, there is no silver bullet to boost your code to stellar-performance. There are a few quick fixes, like efficient functions and handy automations. To really make your code shine, however, you’ll also need to adopt long-term habits like keeping your code as simple as possible and being consistent with your style.
就像生活中的一切一样,没有万灵药可以将您的代码提升为出色的性能。 有一些快速修复程序,例如高效功能和便捷的自动化。 但是,要使您的代码真正发光,您还需要养成长期的习惯,例如,使代码尽可能简单,并与样式保持一致。
使用更有效的功能和结构 (Using more efficient functions and structures)
避免F弦打string (Avoid string hiccups with f-strings)
From processing input to printing messages on the screen, strings are a vital part of any programming language. In Python, there are three ways of formatting strings: the original %s
-method, the str.format()
, and, since Python 3.6, f-strings.
从处理输入到在屏幕上打印消息,字符串是任何编程语言的重要组成部分。 在Python中,有三种格式化字符串的方式:原始%s
-method, str.format()
以及从Python 3.6开始的f字符串。
The good old %s
-method is fine when you’re dealing with short expressions. All you need to do is mark the places where you’d like to insert your string with %s
, and then reference these strings after the statement. Like this:
处理短表达式时,旧的%s
方法很好。 您需要做的就是用%s
标记要插入字符串%s
,然后在语句后引用这些字符串。 像这样:
>>> name = "Monty"
>>> day = "Tuesday"
>>> "Happy %s, %s. Welcome to Python!" % (day, name)'Happy Tuesday, Monty. Welcome to Python!'
This is all well and good, but it gets messy when you’re dealing with a lot of strings at a time. That’s why Python introduced str.format()
from version 2.6 on.
这一切都很好,但是当您一次处理很多字符串时,它会变得混乱。 这就是Python从2.6版本开始引入str.format()
的原因。
Essentially, the %s
symbols are replaced by curly braces. Like so:
本质上, %s
符号用花括号代替。 像这样:
>>> "Happy {}, {}. Welcome to Python!".format(day, name)
The real perk of str.format()
is that you’re now able to define objects and then reference them in your formatting statement:
str.format()
的真正str.format()
是,您现在可以定义对象,然后在格式语句中引用它们:
>>> greeting = {'name': 'Monty', 'day': 'Tuesday'}
>>> "Happy {day}, {name}. Welcome to Python!".format(day=greeting['day'], name=greeting['name'])
This is a huge improvement, but f-strings are even more straightforward. Consider this:
这是一个巨大的改进,但是f字符串甚至更简单。 考虑一下:
>>> name = "Monty"
>>> day = "Tuesday"
>>> f"Happy {day}, {name}. Welcome to Python!"
This is even easier! What’s even nicer about f-strings, though, is that you can pass functions in them:
这更容易! 但是,关于f字符串更好的是,您可以在其中传递函数:
>>> f"Happy {day}, {name.upper()}. Welcome to Python!"'Happy Tuesday, MONTY. Welcome to Python!'
One last upside of f-strings is that they’re faster than the two other methods. Since they’re very straightforward, it makes perfect sense to start using them from now onwards.
f字符串的最后一个好处是它们比其他两种方法更快 。 由于它们非常简单明了,因此从现在开始使用它们是非常有意义的。
使用清单理解 (Use list comprehensions)
List comprehensions are a neat way of making your code more concise while maintaining readability. Consider this piece of code, where we’re trying to store the first few square numbers in a list:
列表理解是使代码更简洁同时保持可读性的一种巧妙方法。 考虑这段代码,我们试图将前几个平方数存储在列表中:
>>> square_numbers = [0, 1, 2, 3, 4]
>>> for x in range(5):
... square_numbers.append(x**2)
...
>>> square_numbers[0, 1, 2, 3, 4, 0, 1, 4, 9, 16]
This is quite clunky, and we’ll have to delete the first few items from the list again. Also, we still have the variable x
floating around and taking up memory. With a list comprehension, this becomes a lot more concise:
这很笨拙,我们必须再次从列表中删除前几项。 同样,我们仍然有变量x
浮动并占用内存。 通过列表理解,这变得更加简洁:
>>> square_numbers = [x**2 for x in range(5)]
>>> square_numbers[0, 1, 4, 9, 16]
The syntax is fairly easy:
语法非常简单:
new_list = [expression for item in iterable (if conditional)]
So the next time you’re about to make a list with a for
loop, and perhaps an if
statement, think again. You could save a few lines of code every time.
因此,下一次您将要创建一个带有for
循环以及if
语句的列表时,请三思。 您每次可以节省几行代码。
快速创建长度为N的列表 (Create length-N lists quickly)
Initializing lists in Python is easy. But you can up your game by using the *
operator, for example like this:
用Python初始化列表很容易。 但是,您最多可以使用您的游戏*
运营商,比如像这样 :
>>> four_nones = [None] * 4
>>> four_nones[None, None, None, None]
If you want to create a list of lists, you can use a list concatenation:
如果要创建列表列表,可以使用列表串联:
>>> four_lists = [[] for __ in range(4)]
>>> four_lists[[], [], [], []]
This comes handy when you’re trying to initialize long lists, or lists of lists. Not only is it easier to read and to debug, but you’re also less likely to make typos in individual elements of the list.
当您尝试初始化长列表或列表列表时,这很方便。 不仅更易于阅读和调试,而且您也不太可能在列表的各个元素中打错字。
删除列表元素时要小心 (Be careful with deleting elements of lists)
Consider a list a
where we want to delete all items that are equal to bar
. We can use a for-loop to get that done:
考虑一个列表a
我们想要删除等于所有项目bar
。 我们可以使用for循环来完成此任务:
>>> a = ['foo', 'foo', 'bar', 'bar']
>>> for i in a:
... if i == 'bar':
... a.remove(i)
...
>>> a['foo', 'foo', 'bar']
But one bar
is remaining! What happened?
但是只剩下一个bar
! 发生了什么?
Well, when i was in positions 0 and 1, it correctly recognized that those elements need not be removed. At i = 2
, it deleted bar
. Now the second bar
moved to position 2
. But now the loop has already ended because there is no more element at i = 3
, therefore the second bar
remains.
好吧,当我处于位置0和1时,它正确地认识到不需要删除这些元素。 在i = 2
,它删除了bar
。 现在第二bar
移到位置2
。 但是现在循环已经结束了,因为在i = 3
处没有更多元素,因此第二bar
仍然保留。
In short, don’t use for
loops when you’re deleting items from a list. Although you can avoid this kind of mistake with a few fixes, they’re just very prone to errors. Instead, the list comprehension comes in handy again:
简而言之,当您从列表中删除项目时,请勿使用for
循环。 尽管您可以通过一些修复来避免这种错误,但是它们很容易出错。 相反,列表理解再次派上用场:
>>> foos = [value for value in a if value != 'bar']
>>> foos['foo', 'foo']
优雅地访问字典元素 (Access dictionary elements elegantly)
Using dict.get()
to access elements of a dictionary is clunky and error-prone. Consider this example:
使用dict.get()
来访问字典中的元素比较麻烦且容易出错。 考虑这个例子 :
>>> d = {
'hello': 'world'}
>>> if d.has_key('hello'):
... print d['hello'] # prints 'world'
>>> else:
... print 'default_value'
It’s a lot more concise if you use dict.get()
:
如果使用dict.get()
它会更加简洁:
>>> d.get('hello', 'default_value') # prints 'world'
>>> d.get('thingy', 'default_value') # prints 'default_value'
Or, if you want it even shorter, you can write:
或者,如果您希望更短一些,可以编写:
>>> if 'hello' in d:
... d['hello']
用*,**和_解压缩参数 (Unpack arguments with *, **, and _)
What do you do when you have a list but you don’t need all arguments? You can use _
for that:
有列表但不需要所有参数时该怎么办? 您可以使用_
:
>>> numbers = [1, 2, 3]
>>> a, b, _ = numbers
>>> a
1
The underscore is conventionally used to tell the programmer that this variable is not worth remembering. While Python does remember the variable, using this convention adds to the readability of your code.
下划线通常用于告诉程序员该变量不值得记住。 尽管Python确实记住了该变量,但是使用此约定可以增加代码的可读性。
If you have a long list, but you’re only interested in the first or last few variables, you can do this:
如果列表很长,但是只对前几个或最后几个变量感兴趣,则可以执行以下操作:
>>> long_list = [x for x in range(100)]
>>> a, b, *c, d, e, f = long_list
>>> e
98
A variable beginning with *
can hold as any number of elements. In this example, we’ve created a list going from 0 to 99, and unpacked the first two and last three elements. Specifically, the next-to-last element, e
, is 98, which we’d expected.
以*
开头的变量可以容纳任意数量的元素。 在此示例中,我们创建了一个从0到99的列表,并解压缩了前两个元素和最后三个元素。 具体来说,倒数第二个元素e
是我们期望的98。
You can also use the *
operator to pass any number of arguments to a function:
您还可以使用*
运算符将任意数量的参数传递给函数:
>>> def printfunction(*args):
... print(args)
>>> printfunction(1,2,3,4,5,6)(1, 2, 3, 4, 5, 6)
Finally, you can use the **
operator to pass entire dictionaries to a function:
最后,您可以使用**
运算符将整个字典传递给一个函数:
>>> def myfriendsfunction(name, age, profession):
... print("Name: ", name)
... print("Age: ", age)
... print("Profession: ", profession)
>>> friendanne = {"name": "Anne", "age": 26, "profession": "Senior Developer"}
>>> myfriendsfunction(**friendanne)Name: Anne
Age: 26
Profession: Senior Developer
These are quick and easy ways to access variables without too much fuss. Keep them in mind!
这些是访问变量而又不必大惊小怪的快速简便的方法。 记住他们!
自动打开和关闭文件 (Automate opening and closing files)
The traditional way of opening files implies that you need to close them again:
传统的打开文件方式意味着您需要再次关闭它们:
>>> newfile = open("file.txt")
>>> data = newfile.read()
>>> print(data)
>>> newfile.close()
You can save a line and the potential to introduce bugs by using with open
:
通过with open
使用with open
可以节省一行代码并可能引入错误:
>>> with open('file.txt') as f:
>>> for line in f:
>>> print line
This way, even if an exception is raised within the with
block, the file will be closed again.
这样,即使with
块中引发了异常,该文件也会再次关闭 。
快速获取信息 (Getting quick information)
在前往StackOverflow之前使用help() (Use help() before heading to StackOverflow)
If you’d like to see what a function does, just use help()
. This is useful if you know in principle what you’re doing but aren’t too sure about the details of a function.
如果您想查看函数的功能,请使用help()
。 如果您原则上知道自己在做什么,但对功能的细节不太确定,则这很有用。
You can also make your life easier by adding a help-message to your own functions. That’s quite easy to pull off:
您还可以通过在自己的功能中添加帮助消息来简化生活。 这很容易实现:
>>> def mynewfunction(arg1, arg2):
... """
... This function does something really cool.
... Hope that helps!
... """
>>> help(mynewfunction)This function does something really cool.
Hope that helps!
This help-message, a docstring, is also useful as a documentation of your code. In this example, you’d obviously need to add a body to the function and flesh the message out a bit. But you get the message.
此帮助消息(docstring)也可用作代码的文档。 在此示例中,您显然需要向该函数添加主体并将消息充实一些。 但是您会收到消息。
使用dir()了解属性和方法 (Use dir() to learn about attributes and methods)
If you’re not quite sure about how an object works, dir()
can help you. It returns the attributes and methods of whichever function, module, list, dictionary, or other object you wish to learn about.
如果您不确定对象的工作方式, dir()
可以为您提供帮助。 它返回您想学习的任何函数,模块,列表,字典或其他对象的属性和方法。
The dir()
function is available from Python 2.7 onwards. So for most Python users, using this might be a nice option.
dir()
函数从Python 2.7开始可用。 因此,对于大多数Python用户而言,使用它可能是一个不错的选择。
使用getsizeof()优化内存 (Optimize your memory with getsizeof())
If your program is sluggish and you think it has to do with memory issues, you can check through your objects with getsizeof()
to understand where the culprit is. That is fairly easy:
如果您的程序运行缓慢,并且您认为它与内存问题有关,则可以使用getsizeof()
检查对象以了解问题所在。 那很简单:
>>> import sys
>>> x = [1, 2, 3, 4, 5]
>>> sys.getsizeof(x)112
Since x
is a vector made of five 24-bit integers on my machine, it makes perfect sense that it takes up 112 bit of memory. Note that this number varies a bit, depending on your machine, architecture, and Python version.
由于x
是我的机器上由五个24位整数组成的向量,因此完全占用112位内存是很有意义的。 请注意,此数字略有不同,具体取决于您的计算机,体系结构和Python版本。
使文档更容易 (Making documentation easier)
选择您的文档字符串样式并保持不变 (Choose your docstring style and keep to it)
As mentioned above, adding docstrings to all your module, function, class, or method definitions is an extremely good idea.
如上所述,向所有模块,函数,类或方法定义中添加文档字符串是一个非常好的主意。
To make your code as maintainable and readable as possible, you’ll want to choose one docstring style and stick to that. If you’re collaborating on a project, make sure that you’ve decided on one style from the beginning. This makes it a lot easier to read and to add to the documentation later on.
为了使代码尽可能易于维护和可读,您需要选择一种文档字符串样式并坚持使用。 如果要在项目上进行协作,请确保从一开始就已决定一种样式。 这使以后阅读和添加到文档变得容易得多。
版本化您的代码 (Version your code)
Most software projects have a three-digit version number, for example “Python 3.8.4". The system is straightforward — if you’re making minor changes or bug fixes, you change the last number, for larger changes you change the middle number, and for rather fundamental changes you change the first number.
大多数软件项目的版本号都是三位数,例如“ Python 3.8.4”。系统非常简单-如果您进行较小的更改或错误修复,请更改最后一个数字,对于较大的更改,请更改中间数字,并且要进行根本性的更改,请更改第一个数字。
Even if your project is small, there are a few advantages to keeping all the old copies and numbering them. If you’re trying to make a bug fix but you end up breaking something, you can always go back to the latest version. And if your project isn’t backward-compatible, keeping old copies is vital. In addition, this numbering scheme creates a neat change log that you can refer to later.
即使您的项目很小,保留所有旧副本并为其编号也有一些好处。 如果您尝试进行错误修复,但最终却破坏了某些内容,则可以始终使用最新版本。 而且,如果您的项目不向后兼容,那么保留旧副本至关重要。 此外,此编号方案还创建了一个整洁的更改日志,您以后可以参考它。
定期打它 (Git it regularly)
If you’re collaborating or working on an open-source project, this is a must: Put your code on Github, Gitlab, or wherever else you’d like your code to live. This way it’s accessible by anyone at any time.
如果您正在协作或从事开源项目,这是必须的:将代码放在Github,Gitlab或您希望将代码存在于任何其他地方。 这样,任何人都可以随时访问它。
Also, make sure you git it often. Not only does that keep everyone up to date; it’s also a sign that your code is being maintained and still relevant.
另外,请确保您经常搅拌它。 这不仅使每个人都保持最新状态; 这也表明您的代码正在维护并且仍然相关。
保留变更记录 (Keep a change log)
Even if you’re using docstrings and consistently numbering your versions, that won’t capture all the changes you’re making. In order to keep the details safe, it’s a good idea to have a separate document where all changes are explained in detail.
即使您使用文档字符串并对版本进行一致编号,也无法捕获您所做的所有更改。 为了确保细节安全,最好有一个单独的文档,其中详细说明所有更改。
Even though this will hardly be relevant to the end user, your change log will be a valuable document for yourself and for your colleagues later on. The human mind forgets fast, and things that are completely obvious to you now are often pretty opaque in two weeks.
即使这与最终用户几乎没有关系,您的更改日志对于您自己和以后的同事来说都是有价值的文档。 人的大脑会很快忘记,现在对您来说完全显而易见的事情通常在两周之内变得非常模糊。
使用描述性长名称 (Use long and descriptive variable names)
Have you noticed anything about the examples above? The names of functions and variables almost always quite long. That’s no coincidence.
您是否注意到上述示例的任何内容? 函数和变量的名称几乎总是很长。 那不是巧合。
It may seem superfluous to use so many characters for a bit of code, but it’s a lot better for reading the code. Besides, it doesn’t take that much longer to code — most editors have autocomplete anyway.
在代码中使用这么多字符似乎是多余的,但阅读代码要好得多。 此外,编写代码不需要花费太多时间-无论如何,大多数编辑器都具有自动完成功能。
使用PEP 8 (Use PEP 8)
Perhaps you’re one of those developers whose code runs but is sloppily formatted. While that might not sound so tragic, it creates a heap of problems down the road. Not to mention the colleagues that try to read your code…
也许您是那些运行代码但格式不正确的开发人员之一。 尽管这听起来可能并不那么悲惨,但它却在以后产生了很多问题。 更不用说尝试读取您的代码的同事了……
So do yourself a favor and format your code with PEP 8, the official Python style guide. Don’t worry, you don’t need to learn every detail and refactor each piece of your code. You can automatically check whether your code conforms with pycodestyle
. In your shell, install the package, then run it over your Python file:
因此,请帮自己一个忙,并使用官方Python样式指南PEP 8格式化代码。 不用担心,您不需要学习每个细节并重构代码的每一部分。 您可以自动检查您的代码是否符合pycodestyle
。 在您的外壳中,安装软件包,然后在您的Python文件上运行它:
$ pip install pycodestyle
$ pycodestyle my_file.py
This signals where you need to make adjustments so your file conforms to PEP 8. If you want to get your file to conform automatically, you can use autopep8
:
这表明您需要进行调整,以使文件符合PEP 8的要求。如果要使文件自动符合要求,可以使用autopep8
:
$ pip install autopep8
$ autopep8 --in-place my_file.py
好评论 (Comment well)
There’s an ongoing debate about whether comments are good or bad. Some programmers believe that good code is so readable that you don’t need any comments. Others would like you to comment every line.
关于评论是好是坏的争论不断。 一些程序员认为好的代码可读性强,因此您不需要任何注释。 其他人希望您评论每一行。
Unless you are a total purist, you’re at least commenting from time to time. In any case, make sure you keep your comments short and to-the-point. I like to think about what somebody would like to read if they’d never seen my code but had a look at it now because they wanted to change something. That tends to work pretty well.
除非您是一个纯粹主义者,否则您至少会不时发表评论。 无论如何,请确保您的评论简短明了。 我想考虑一个人,如果他们从未看过我的代码,但现在想看一下,因为他们想更改某些内容,因此想要阅读什么。 这往往效果很好。
养成良好的习惯 (Adopting good habits)
使行延续更稳定 (Make line continuations more stable)
In principle, you could split a multi-line expression with a \
at the end of each line, like so:
原则上,您可以在多行表达式的每一行的末尾加上\
, 例如 :
>>> big_string = """This is the beginning of a really long story. \
... It's full of magicians, dragons and fabulous creatures. \
... Needless to say, it's quite scary, too."""
However, this is rather error-prone because it stops working if you put a character behind the \
, even if it’s just a whitespace. It’s better to split it like so:
但是,这很容易出错,因为如果将字符放在\
后面,即使它只是一个空格,它也会停止工作。 最好像这样拆分它:
>>> big_string = (
... "This is the beginning of a really long story. "
... "It's full of magicians, dragons and fabulous creatures. "
... "Needless to say, it's quite scary, too."
... )
Most of the time, however, a multi-line expression is a sign that you’re overcomplicating things.
但是,在大多数情况下,多行表达式表示您过于复杂了。
不要写意粉代码 (Don’t write spaghetti code)
This should be a no-brainer, but it’s astounding how many junior developers still write monolithic code. But nobody reads a thousand lines of code…
这应该很容易,但是令人震惊的是有多少初级开发人员仍在编写整体代码。 但是没有人读一千行代码……
So make sure that you define functions and call them when necessary. This will make your code a thousand times more readable, and your colleagues will thank you for it.
因此,请确保定义函数并在必要时调用它们。 这将使您的代码可读性提高一千倍,您的同事将为此感谢您。
每行仅使用一条语句 (Only use one statement per line)
This goes in a similar direction. Don’t do stuff like this:
这朝着相似的方向发展。 不要做这样的事情:
print("one"); print("two")
It might look sophisticated, but it’s not. When you get an error in a specific line, you’ll want to know exactly what that line does so you can debug it quickly. So split it up; each line does its own thing.
它看起来很复杂,但事实并非如此。 当您在特定行中遇到错误时,您将希望确切地知道该行的功能,以便快速调试它。 所以把它分开; 每行都做自己的事。
使用类型提示 (Use type hinting)
Python is a dynamically typed language. While that’s great to for producing code quickly, it can make debugging harder.
Python是一种动态类型的语言。 尽管这对于快速生成代码非常有用,但它会使调试更加困难。
Since Python 3.5, you can prepare for debugging by adding type hinting. That doesn’t affect the code since the interpreter ignores it. But it’s helpful for you because you can instantly see if you’re passing something wrong to a function.
从Python 3.5开始,您可以通过添加类型提示来准备调试。 这不会影响代码,因为解释器会忽略它。 但这对您很有帮助,因为您可以立即查看是否将错误传递给函数。
Type hinting works like in the following example:
类型提示的工作方式类似于以下示例:
>>> def sayhello(day:str, name:str) -> str:
... return f"Happy {day}, {name}. Welcome to Python!"
The :str
indicates that the arguments of the function are expected to be strings, and the -> str
part indicates that the function should return a string.
:str
表示函数的参数应为字符串, -> str
部分表示函数应返回字符串。
最重要的是:Python很棒。 更好的Python很棒 (The bottom line: Python is great. Better Python is amazing)
Don’t settle for second best. The fact that Python is still the indisputable king of general-purpose programming languages is no excuse for writing mediocre code.
不要争取第二好的。 Python仍然是通用编程语言中无可争议的王者,这并不是编写平庸代码的借口。
You’ll make your code stand out by keeping to style conventions, documenting changes properly, and keeping your code concise. In some cases, that will even improve its performance. In any case, it will make it much easier for you and your colleagues to read and maintain the code.
通过遵循样式约定,正确记录更改并保持代码简洁,可以使您的代码脱颖而出。 在某些情况下,这甚至可以改善其性能。 无论如何,这将使您和您的同事更容易阅读和维护代码。
While this list contains a whole lot of tips and tricks for you, it’s certainly not exhaustive. If I’ve missed anything, let me know in the comments. In the meantime, happy coding!
尽管此列表包含了许多技巧和窍门,但它当然并不详尽。 如果我错过了任何事情,请在评论中让我知道。 同时,祝您编程愉快!
Edit: As Wink Saville pointed out, the result of getsizeof()
varies, depending on the machine, architecture and Python version. That’s included now. Also, Oliver Farren correctly stated that the underscore _
is indeed a variable that takes up memory. The text now includes that using the underscore a convention that adds to readability. And as Michael Frederickson pointed out on Twitter, the dir()
function is available from Python 2.7 onwards. The story had mistakenly stated that it’s available from Python 3 only.
编辑:正如 Wink Saville 指出的那样, getsizeof()
的结果 因机器,体系结构和Python版本而异。 现在包括在内。 另外, Oliver Farren 正确地指出,下划线 _
确实是占用内存的变量。 文本现在包括使用下划线的约定,以增加可读性。 正如 迈克尔·弗雷德里克森 ( Michael Frederickson) 在Twitter上指出的那样, dir()
函数可从Python 2.7开始使用。 这个故事错误地指出了它仅可用于Python 3。
翻译自: https://towardsdatascience.com/the-ultimate-guide-to-writing-better-python-code-1362a1209e5a
python代码编写工具