每个Python程序员都应该知道的10个缩写
重磅干货,第一时间送达
介绍
对于许多刚开始学习代码的人来说,Python已经成为最佳的选择。它的语法非常直观,并且支持灵活的动态类型。另外,它是一种解释性语言,可以将交互式控制台用于学习。基本上,我们可以仅使用一些命令行工具(例如Mac中的Terminal)来开始Python学习,因为macOS现已随Python一起提供。
学习Python时,我摸会逐渐熟悉它的数据结构,控制流,类,函数和其他基本知识。有趣的是Python中的各种首字母缩写词,我们时常会遇到。本文将回顾十个这样的缩写。其中一些是通用的编程原理,而另一些则更特定于Python编码。然而,它们每个都有其有趣的方面。
1. OOP(面向对象编程)
我们应该知道的第一个缩写是OOP —面向对象编程,Python就是基于此进行设计的。我们知道编程本身是关于编码的,但是程序本身应该是关于数据的。我们的程序需要获取输入数据,过程中处理数据,最后输出数据。但请注意,此处讨论的数据是最一般意义上的数据,可以包括表格数据,字符串,用户操作(例如,单击按钮),图像以及具有信息的任何形式的数据。我们代码的工作是处理这些各种形式的数据,并以所需的方式呈现它们。
为了完成我们的工作,我们需要能够处理这些数据的代码,而现代编程语言(包括Python)中的一种常见设计模式就是采用OOP范式。这个想法非常直观-我们用特定的对象包装数据。更具体地的说,对象可以保存数据(例如,属性)并且可以操作数据(例如,方法)。例如,如果我们开发一个赛车游戏。我们可以构建汽车对象,每个对象都可以具有特定的属性,例如颜色,最大速度和重量。此外,这些对象还可以进行制动和加速等操作。这些数据的逻辑组织以对象(汽车)为中心。
让我们看一下Python中的一个示例。使用内置的str类包装字符串数据,我们可以使用字符串对象传递字符串数据,还可以改变字符串的表示方式。下面是一个简单的示例。
>>> # Create a variable of str type
... hello = "Hello Python!"
...
... # Send the data to a function call
... print(hello)
...
... # Manipulate the string data with string methods
... hello_lower = hello.lower()
... hello_upper = hello.upper()
... print('lowercased:', hello_lower)
... print('uppercased:', hello_upper)
...
Hello Python!
lowercased: hello python!
uppercased: HELLO PYTHON!
2.DRY (Don’t Repeat Yourself)
DRY(Don’t Repeat Yourself)的原理每个程序员都应该实践。这个想法很简单- 如果代码中有重复,则表明我们需要进行一些重构以最大程度地减少重复代码,或者尽可能消除重复。以下伪代码通过代码的重构展示了DRY原理。
def do_something(item):
pass
# Repetative work
do_something(item0)
do_something(item1)
do_something(item2)
# Apply DRY
for item in (item0, item1, item3):
do_something(item)
代码重构的另一种可能情况是,我们发现自己要处理一堆结构相同的数据。这时我们应该使用自己的类来处理这些数据,而不是使用一系列的字典,列表或元组来存储每个人的数据。这使代码不易出错,而且对后期维护也有好处。
3. PIP(Package Installer for Python)
可能是Python受欢迎的最重要因素是其开放源代码性质,这带来了大量免费的Python软件包集合。根据Wikipedia的介绍,在Python软件包索引(PyPI)中索引了235,000多个软件包。我们可以使用pip工具从PyPI安装任何软件包。该安装过程非常轻松,只需在命令或终端中使用一行代码即可。以下代码段总结了一些常用用法。
# install latest version
pip install package_name
# install a particular version
pip install package_name==version_number
# to uninstall a package
pip uninstall package_name
# to show installed packages
pip list
# to show the information about a particular package
pip show package_name
# to install a list of dependencies, such as to clone a virtual environment
pip install -r requirements.txt
4. LEGB(Local, Enclosing, Global and Built-in)
LEGB规则引用Python中的变量查找顺序,如下图所示。具体来说,当解释程序尝试解析变量时,Python具有四层作用域。首先从局部作用域开始,该作用域可以是函数或类。如果解释器找到了变量的相应绑定值,它将停止查找并将变量与该特定值一起使用。
可变分辨率规则
否则,它将在更高层次上(封闭范围)进行查找。封闭范围仅存在于函数的嵌套结构中。具体来说,当在另一个函数中声明一个函数时,我们将内部函数称为内部函数,将外部函数称为外部函数。当解释器尝试解析内部函数范围内使用的变量时,如果无法在局部范围内解析,它将进入封闭范围,即外部函数的局部范围。
如果仍然无法解析封闭范围内的变量,它将进入全局范围。全局作用域通常是模块级别,通常是独立的Python文件。值得注意的是,当程序包导入到当前文件中时,来自导入的函数和类也将成为全局范围的一部分。内置作用域是在启动解释器时加载的函数,类和其他模块,以使这些最基本的对象始终可用(例如,the print和其他内置函数)。
5. MRO(Method Resolution Order)
The Method Resolution Order表示Python或其他编程语言如何解析方法或属性。与上面讨论的LEGB规则关注的是解决变量不同,MRO关注的是对象以及对象的方法调用或特定属性的获取如何解决。MRO主要是在多继承的上下文中讨论的-从多个类(即超类)和/或多层继承继承的类(即子类)。因为子类和超类都共享一些实现方法可能不同的通用方法,所以Python解释器需要一种机制来确定在特定调用中应使用哪种方法或属性,而这正是MRO的职责。下面的代码段显示了一个示意性示例。
>>> class X:
... def bin(self):
... print(f"bin called in X")
...
... class Y(X):
... def go(self):
... print(f"go called Y")
...
... class Z(X):
... def go(self):
... print(f"go called Z")
...
... class W(Y, Z):
... def bin(self):
... super().bin()
... print(f"bin called W")
...
... def bingo(self):
... self.bin()
... self.go()
...
... w = W()
... w.bingo()
...
bin called in X
bin called W
go called Y
对于W类的实例(第22行),当我们调用bingo()方法时,该方法将在其自己的类中解析,因为它是在类中定义的(第18-20行)。但是,此方法将进一步调用bin()和go()方法。以类似的方式,该bin()方法在其自己的类中解析,但是,它调用超类的bin()方法,如第15行所示。但是在其直接超类(即Y和Z)中,都没有实现该bin()方法,因此Python会继续使用甚至比bin()实现和调用该方法的超类的超类(即X)高一级。
值得注意的是,对于W的go()方法,其两个超类都实现了此方法,但是只有Y类中使用的实现才被调用。这是因为当我们定义W类时,继承顺序是Y和Z,这将使MRO遵循相同的顺序。与此相关,我们可以使用特殊方法找出特定类的MRO __mro__,如下所示。另外,为了展示类继承的顺序的重要性,我们创建了另一个类,其中Z类位于Y类之前,这将更改W_类的MRO。
>>> print('W Class MRO:', W.__mro__)
...
... class W_(Z, Y):
... pass
...
... print('W_ Class MRO:', W_.__mro__)
...
W Class MRO: (<class '__main__.W'>, <class '__main__.Y'>, <class '__main__.Z'>, <class '__main__.X'>, <class 'object'>)
W_ Class MRO: (<class '__main__.W_'>, <class '__main__.Z'>, <class '__main__.Y'>, <class '__main__.X'>, <class 'object'>)
6.&7. EAFP(Easier to Ask Forgiveness than Permission)和LBYL(Look Before Your Leap)
EAFP(Easier to Ask Forgiveness than Permission)编码风格是Python赖以生存的基础。因为Python是一种动态编程语言,所以在运行时可以对现有的实例对象、类或模块进行实现和修改。因此在假定特殊属性或功能可用的情况下编写代码。换句话说,如果某些代码可能存在特定问题,则让问题浮出水面并相应地解决它们。通过应用EAFP规则,如果我们想更进一步,我们可以简单地使用try ... except编写特定的代码。用语句来处理代码可能引发的潜在异常的问题。即先考虑发生哪些意外情况,事后再进行处理。
与EAFP原理相反,还有另一种称为LBYL的编码样式,它代表“跨越式”。通过这种编码方式,程序员有望在运行某些代码之前排除所有可能的不良情况。因此,在遵循LBYL原则的项目中看到更多if语句。基本上,这种编码样式试图临时解决所有问题。
以下代码段显示了使用EAFP与LBYL的可能方案。使用EAFP编码样式,我们只需在try…except语句中包装我们的代码和可能的异常,而使用LBYL编码样式,我们必须使在之前验证适用条件。如您所见,EAFP代码看起来很干净,而没有创建嵌套结构。当然,我们也可以在项目中应用LBYL。
def with_EAFP_divide_ten_by(number):
try:
print(f'10 divided by {number} is {10 / number}.')
except ZeroDivisionError:
print("You can't divide zero.")
except TypeError:
print("You can only divide a number.")
def with_LBYL_divide_ten_by(number):
if isinstance(number, int) or isinstance(number, float):
if number == 0:
print("You can't divide zero.")
else:
print(f'10 divided by {number} is {10 / number}.')
else:
print("You can only divide a number.")
8. PEP(Python Enhancement Proposals)
上一节讨论了编码风格。但是,最具影响力的Python编码样式指南之一是PEP 8,由BDFL(将在下面讨论)和其他几个Python核心维护者编写。PEP涵盖了很多内容-所有与Python相关的内容。我们可以在官方网站上找到所有内容。这里列出了一些比较著名的文章。
PEP 8:Python代码样式指南
PEP 257:Docstring约定
PEP 20:Python的禅宗
PEP 498:文字字符串插值
PEP 202:列表理解
PEP 405:Python虚拟环境
9. BDFL(Benevolent Dictator For Life)
什么是BDFL?当然,章节标题已告诉您它代表什么,但实际上是什么意思呢?下面使维基百科中的定义。
Benevolent dictator for life (BDFL) is a title given to a small number of open-source software development leaders, typically project founders who retain the final say in disputes or arguments within the community.
尽管此定义通常适用于任何开源语言的软件开发,但它最初在Python社区中使用时,由Python编程语言的创建者Guido van Rossum(GvR)担任。担任BDFL角色20多年之后,他于2018年卸任。如果对BDFL的故事感兴趣,可以去Wikipedia上阅读更多内容。
10. REPL(Read-Eval-Print Loop)
在我看来,REPL(读取-评估-打印循环)是使学习Python如此轻松的便捷工具。我们可以开始像使用命令或终端窗口一样,pip工具将软件包安装在此处。更重要的是,我们可以立即编写第一行Python代码(例如,print(“Hello World!”)),而无需使用其他编程语言或配置任何IDE工具。让我们看一下它的外观。
>>> print("Hello World!")
Hello World!
>>> 3 * 2
6
>>> type(5)
<class 'int'>
REPL工作流程非常简单-读取代码,对其进行评估并在控制台中打印评估中的所有适用结果,然后一次又一次地重复这三个步骤以探索Python的各种功能。REPL在标准Python或其他常见的Python开发工具(例如ipython)中作为默认模式实现。
Python是一种灵活而强大的OOP语言,它是由BDFL GvR创建的。利用PIP,我们可以轻松地管理Python软件包,并通过REPL在控制台中学习语言和各种软件包。当我们使用Python进行编码时,我们希望遵循PEP 8中概述的样式。其他重要的编码原理包括DRY和EAFP。如果愿意,也可以在编码中做一些LBYL。LEGB规则和MRO将帮助我们了解如何解析变量,属性和函数以使代码的预期运行效果。
交流群