Python 入门指南(一)(2)

简介: Python 入门指南(一)

Python 入门指南(一)(1)https://developer.aliyun.com/article/1507353

Python 的执行模型

在这一部分,我想向你介绍一些非常重要的概念,比如作用域、名称和命名空间。当然,你可以在官方语言参考中阅读关于 Python 执行模型的所有内容,但我认为那相当技术化和抽象,所以让我先给你一个不太正式的解释。

名称和命名空间

假设你正在找一本书,所以你去图书馆问有人要找的书。他们告诉你类似二楼,X 区,第三排这样的信息。于是你上楼,找到 X 区,依此类推。

进入一个图书馆,所有的书都堆在一起,没有楼层,没有区域,没有排列,没有秩序,那将是非常不同的。找一本书将会非常困难。

当我们编写代码时,我们也会遇到同样的问题:我们必须尝试组织它,以便对于没有先验知识的人来说,能够轻松找到他们要找的东西。当软件结构正确时,它也促进了代码重用。另一方面,杂乱无章的软件更有可能暴露出分散的重复逻辑片段。

首先,让我们从书开始。我们通过书的标题来引用一本书,在 Python 术语中,那将是一个名称。Python 名称是其他语言称为变量的最接近的抽象。名称基本上是指向对象的,并且是通过名称绑定操作引入的。让我们举个快速的例子(注意,跟在#后面的任何内容都是注释):

>>> n = 3  # integer number
>>> address = "221b Baker Street, NW1 6XE, London"  # Sherlock Holmes' address
>>> employee = {
...     'age': 45,
...     'role': 'CTO',
...     'SSN': 'AB1234567',
... }
>>> # let's print them
>>> n
3
>>> address
'221b Baker Street, NW1 6XE, London'
>>> employee
{'age': 45, 'role': 'CTO', 'SSN': 'AB1234567'}
>>> other_name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'other_name' is not defined 

我们在前面的代码中定义了三个对象(你还记得每个 Python 对象具有的三个特征是什么吗?):

  • 一个整数n(类型:int,值:3
  • 一个字符串address(类型:str,值:福尔摩斯的地址)
  • 一个字典employee(类型:dict,值:包含三个键/值对的字典)

别担心,我知道你不应该知道什么是字典。我们将在第二章“内置数据类型”中看到,它是 Python 数据结构的王者。

你有没有注意到,当我输入 employee 的定义时,提示从>>>变成了...?这是因为定义跨越了多行。

那么,naddressemployee是什么?它们是名称。我们可以使用这些名称在我们的代码中检索数据。它们需要被保存在某个地方,这样每当我们需要检索这些对象时,我们可以使用它们的名称来获取它们。我们需要一些空间来保存它们,因此:命名空间!

命名空间因此是名称到对象的映射。例如内置名称集(包含在任何 Python 程序中始终可访问的函数)、模块中的全局名称和函数中的局部名称。甚至对象的属性集也可以被视为命名空间。

命名空间的美妙之处在于它们允许你以清晰的方式定义和组织你的名称,而不会重叠或干扰。例如,与我们在图书馆中寻找的书相关联的命名空间可以用来导入书本本身,就像这样:

from library.second_floor.section_x.row_three import book 

我们从library命名空间开始,通过点(.)运算符,我们进入该命名空间。在这个命名空间中,我们寻找second_floor,再次使用.运算符进入它。然后我们进入section_x,最后在最后一个命名空间row_three中找到了我们正在寻找的名称:book

当我们处理真实的代码示例时,通过命名空间的遍历将更加清晰。现在,只需记住命名空间是名称与对象相关联的地方。

还有一个概念,与命名空间的概念密切相关,我想简要谈谈:作用域

作用域

根据 Python 的文档:

作用域是 Python 程序的文本区域,其中命名空间是直接可访问的。”

直接可访问意味着当你寻找一个未经修饰的名称引用时,Python 会尝试在命名空间中找到它。

作用域是静态确定的,但实际上,在运行时,它们是动态使用的。这意味着通过检查源代码,你可以知道对象的作用域是什么,但这并不阻止软件在运行时改变它。Python 提供了四种不同的作用域(当然,不一定同时都存在):

  • 局部作用域,它是最内层的作用域,包含局部名称。
  • 封闭作用域,也就是任何封闭函数的作用域。它包含非局部名称和非全局名称。
  • 全局作用域包含全局名称。
  • 内置作用域包含内置名称。Python 带有一组函数,你可以直接使用,比如printallabs等。它们存在于内置作用域中。

规则如下:当我们引用一个名称时,Python 会从当前命名空间开始查找它。如果找不到该名称,Python 会继续搜索封闭范围,直到搜索内置范围。如果在搜索内置范围后没有找到名称,则 Python 会引发一个NameError异常,这基本上意味着该名称尚未定义(您在前面的示例中看到了这一点)。

当查找名称时,命名空间的扫描顺序是:本地封闭全局内置LEGB)。

这都是非常理论的,所以让我们看一个例子。为了向您展示本地和封闭命名空间,我将不得不定义一些函数。如果您暂时不熟悉它们的语法,不要担心。我们将在第四章中学习函数,代码的构建块。只需记住,在下面的代码中,当您看到def时,这意味着我正在定义一个函数:

# scopes1.py
# Local versus Global
# we define a function, called local
def local():
    m = 7
    print(m)
m = 5
print(m)
# we call, or `execute` the function local
local()

在前面的示例中,我们在全局范围和本地范围(由local函数定义)中定义了相同的名称m。当我们使用以下命令执行此程序时(您已激活了您的虚拟环境吗?):

$ python scopes1.py

我们在控制台上看到两个数字打印出来:57

Python 解释器解析文件时,从上到下。首先找到一对注释行,然后解析函数local的定义。调用时,此函数执行两件事:它设置一个名称到代表数字7的对象,并将其打印出来。Python 解释器继续前进,找到另一个名称绑定。这次绑定发生在全局范围中,值为5。下一行是对print函数的调用,它被执行(因此我们在控制台上得到了第一个打印出的值:5)。

在此之后,调用函数local。此时,Python 执行该函数,因此此时发生绑定m = 7并打印出来。

非常重要的一点是代码的一部分属于local函数的定义,右侧缩进了四个空格。事实上,Python 通过缩进代码来定义作用域。通过缩进进入作用域,通过取消缩进退出作用域。一些编码人员使用两个空格,其他人使用三个空格,但建议使用的空格数是四个。这是最大化可读性的一个很好的措施。我们稍后会更多地讨论编写 Python 代码时应该采用的所有惯例。

如果我们删除m = 7这一行会发生什么?记住 LEGB 规则。Python 会开始在本地范围(函数local)中查找m,找不到,它会转到下一个封闭范围。在这种情况下,下一个是全局范围,因为没有包裹在local周围的封闭函数。因此,我们会在控制台上看到两个数字5。让我们实际看一下代码会是什么样子:

# scopes2.py
# Local versus Global
def local():
    # m doesn't belong to the scope defined by the local function
    # so Python will keep looking into the next enclosing scope.
    # m is finally found in the global scope
    print(m, 'printing from the local scope')
m = 5
print(m, 'printing from the global scope')
local()

运行scopes2.py将打印出:

$ python scopes2.py
5 printing from the global scope
5 printing from the local scope

正如预期的那样,Python 首次打印m,然后当调用函数local时,m在其范围内找不到,因此 Python 按照 LEGB 链继续寻找,直到在全局范围中找到m

让我们看一个带有额外层次的示例,封闭范围:

# scopes3.py
# Local, Enclosing and Global
def enclosing_func():
    m = 13
    def local():
        # m doesn't belong to the scope defined by the local
        # function so Python will keep looking into the next
        # enclosing scope. This time m is found in the enclosing
        # scope
        print(m, 'printing from the local scope')
    # calling the function local
    local()
m = 5
print(m, 'printing from the global scope')
enclosing_func()

运行scopes3.py将在控制台上打印:

$ python scopes3.py
(5, 'printing from the global scope')
(13, 'printing from the local scope')

正如您所看到的,函数local中的print指令与以前一样引用mm在函数本身中仍未定义,因此 Python 按照 LEGB 顺序开始遍历范围。这次m在封闭范围中找到。

现在如果这还不是很清楚,不要担心。随着我们在书中的例子,你会慢慢理解的。Python 教程的Classes部分(docs.python.org/3/tutorial/classes.html)有一段有趣的关于作用域和命名空间的段落。如果你想更深入地理解这个主题,一定要在某个时候阅读一下。

在我们结束这一章之前,我想再多谈谈对象。毕竟,基本上 Python 中的一切都是对象,所以我认为它们值得更多的关注。

对象和类

当我之前在章节A proper introduction中介绍对象时,我说我们用它们来代表现实生活中的对象。例如,现在我们在网上销售各种商品,我们需要能够正确地处理、存储和表示它们。但对象实际上远不止于此。在 Python 中,你将要做的大部分事情都与操作对象有关。

因此,不要深入细节(我们将在以后的章节中做到这一点),我想给你一个关于类和对象的简而言之的解释。

我们已经看到对象是 Python 对数据的抽象。事实上,Python 中的一切都是对象,包括数字,字符串(保存文本的数据结构),容器,集合,甚至函数。你可以把它们想象成至少有三个特征的盒子:一个 ID(唯一),一个类型和一个值。

但它们是如何产生的?我们如何创建它们?我们如何编写我们自己的自定义对象?答案就在一个简单的词中:

事实上,对象是类的实例。Python 的美妙之处在于类本身也是对象,但我们不要深入这个领域。这会导致这种语言中最高级的概念之一:元类。现在,你理解类和对象之间的区别最好的方法是通过一个例子。

比如一个朋友告诉你,我买了一辆新自行车! 你立刻明白她在说什么。你看到了这辆自行车吗?没有。你知道它是什么颜色吗?不知道。品牌?不知道。你对它了解多少?不知道。但与此同时,你知道你需要了解的一切,以理解你的朋友告诉你她买了一辆新自行车。你知道自行车有两个轮子连接到一个框架上,有一个鞍座,踏板,把手,刹车等等。换句话说,即使你没有看到自行车本身,你知道自行车的概念。一组抽象的特征和特性共同形成了一个叫做自行车的东西。

在计算机编程中,这就是所谓的。就是这么简单。类用于创建对象。事实上,对象被称为类的实例

换句话说,我们都知道自行车是什么;我们知道这个类。但是我有自己的自行车,它是自行车类的一个实例。我的自行车是一个具有自己特征和方法的对象。你也有自己的自行车。同样的类,但不同的实例。世界上制造的每辆自行车都是自行车类的一个实例。

让我们看一个例子。我们将编写一个定义自行车的类,然后我们将创建两辆自行车,一辆红色的,一辆蓝色的。我会保持代码非常简单,但如果你不完全理解它,不要担心;你现在需要关心的是理解类和对象(或类的实例)之间的区别:

# bike.py
# let's define the class Bike
class Bike:
    def __init__(self, colour, frame_material):
        self.colour = colour
        self.frame_material = frame_material
    def brake(self):
        print("Braking!")
# let's create a couple of instances
red_bike = Bike('Red', 'Carbon fiber')
blue_bike = Bike('Blue', 'Steel')
# let's inspect the objects we have, instances of the Bike class.
print(red_bike.colour)  # prints: Red
print(red_bike.frame_material)  # prints: Carbon fiber
print(blue_bike.colour)  # prints: Blue
print(blue_bike.frame_material)  # prints: Steel
# let's brake!
red_bike.brake()  # prints: Braking!

我希望现在我不需要再告诉你每次都要运行文件了,对吧?文件名在代码块的第一行中指定。只需运行$ python filename,一切都会很好。但记得要激活你的虚拟环境!

这里有很多有趣的事情要注意。首先,类的定义是通过class语句完成的。无论class语句之后的代码是什么,并且缩进,都被称为类的主体。在我们的例子中,属于类定义的最后一行是print("Braking!")

在定义了类之后,我们准备创建实例。你可以看到类主体承载了两个方法的定义。方法基本上(和简单地)是属于类的函数。

第一个方法__init__是一个初始化器。它使用一些 Python 魔术来使用我们在创建时传递的值设置对象。

在 Python 中,每个具有前导和尾随双下划线的方法都被称为魔术方法。魔术方法被 Python 用于多种不同的目的;因此,使用两个前导和尾随下划线命名自定义方法从来都不是一个好主意。这种命名约定最好留给 Python。

我们定义的另一种方法brake只是一个额外方法的示例,如果我们想要刹车自行车,我们可以调用它。当然,它只包含一个print语句;这只是一个例子。

我们创建了两辆自行车。一辆是红色的,有碳纤维框架,另一辆是蓝色的,有钢框架。我们在创建时传递这些值。创建后,我们打印出红色自行车的颜色属性和框架类型,以及蓝色自行车的框架类型,这只是一个例子。我们还调用了red_bikebrake方法。

最后要注意的一件事。你还记得我告诉过你对象的属性集被认为是一个命名空间吗?我希望现在我说的更清楚了。你可以看到通过不同的命名空间(red_bikeblue_bike)获取frame_type属性,我们得到不同的值。没有重叠,没有混淆。

点(.)运算符当然是我们用来进入命名空间的手段,在对象的情况下也是如此。

如何编写良好代码的指南

编写良好的代码并不像看起来那么容易。正如我之前所说,良好的代码展示了一长串相当难以组合的特质。编写良好的代码在某种程度上是一种艺术。无论你愿意在哪个阶段停下来,有一件事你可以接受,那就是让你的代码立即变得更好的东西:PEP 8

根据维基百科:

“Python 的发展主要通过 Python Enhancement Proposal (PEP) 过程进行。PEP 过程是提出主要新功能、收集社区对问题的意见和记录 Python 设计决策的主要机制。”

PEP 8 可能是所有 PEP 中最著名的。它提出了一套简单但有效的指南,定义了 Python 的美学,以便我们编写优美的 Python 代码。如果你从这一章中得到一个建议,请让它成为这个:使用它。拥抱它。你以后会感谢我的。

今天的编码不再是一个签入/签出的业务。相反,它更多的是一种社会努力。几个开发人员通过 Git 和 Mercurial 等工具共同协作一段代码,结果是由许多不同的手所创造的代码。

Git 和 Mercurial 可能是今天使用最多的分布式版本控制系统。它们是设计帮助开发团队共同协作在同一软件上的基本工具。

如今,我们更需要有一种一致的编写代码的方式,以便最大限度地提高可读性。当公司的所有开发人员遵守 PEP 8 时,他们中的任何一个人落在一段代码上,都不会觉得他们自己写的。这实际上经常发生在我身上(我总是忘记我写的代码)。

这有一个巨大的优势:当您阅读自己可以写出的代码时,您会轻松阅读。没有约定,每个编码人员都会按照他们最喜欢的方式或者他们被教导或者习惯的方式来构建代码,这意味着必须根据别人的风格来解释每一行。这意味着要花费更多的时间来理解它。由于 PEP 8,我们可以避免这种情况。我是它的忠实粉丝,如果代码不遵守它,我就不会签署代码审查。因此,请花时间学习它;这非常重要。

在本书的例子中,我会尽量尊重它。不幸的是,我没有 79 个字符的奢侈(这是 PEP 8 建议的最大行长度),我将不得不减少空行和其他东西,但我向你保证我会尽量布置我的代码,使其尽可能可读。

Python 文化

Python 已经被广泛应用于所有编码行业。它被许多不同的公司用于许多不同的目的,也被用于教育(因为它有许多优点,而且易于学习,所以它是一个非常出色的语言)。

Python 今天如此受欢迎的一个原因是,围绕它的社区是庞大、充满活力且充满杰出人才的。世界各地都组织了许多活动,主要是围绕 Python 或其主要的 Web 框架 Django。

Python 是开放的,而且通常拥抱它的人的思想也是开放的。在 Python 网站的社区页面上查看更多信息并参与其中!

Python 还有另一个方面,围绕着“Pythonic”的概念。这与 Python 允许您使用一些在其他地方找不到的习语有关,至少不是以相同的形式或者不是那么容易使用(现在我在使用不是 Python 的语言编码时感到相当幽闭恐惧)。

无论如何,多年来,这种 Pythonic 的概念已经出现了,我理解的方式是按照 Python 应该完成的方式来做事

为了帮助您更好地了解 Python 的文化和 Pythonic,我将向您展示Python 之禅。这是一个非常受欢迎的可爱彩蛋。打开 Python 控制台,键入import this。接下来的内容就是这行的结果:

>>> 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.
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 特性,您将不得不深入理解,以便按照它应该被编写的方式编写 Python。从有趣的层次开始,然后深入挖掘。始终深入挖掘。

关于 IDE 的说明

关于 IDE 的一些话。要遵循本书中的示例,您不需要 IDE;任何文本编辑器都可以。如果您想要更多高级功能,比如语法着色和自动完成,您就需要获取一个 IDE。您可以在 Python 网站上找到一份全面的开源 IDE 列表(只需搜索 Python IDEs)。我个人使用 Sublime Text 编辑器。它是免费试用的,成本只需几美元。我一生中尝试过许多 IDE,但这是让我最有效率的一个。

两个重要的建议:

  • 无论您选择使用什么 IDE,都要努力学会它,以便能够充分利用它的优势,但不要依赖它。偶尔练习使用 VIM(或任何其他文本编辑器);学会能够在任何平台上使用任何一套工具进行工作。
  • 无论您使用什么文本编辑器/IDE,写 Python 时,缩进是四个空格。不要使用制表符,也不要将它们与空格混合使用。使用四个空格,不是两个,不是三个,也不是五个。就使用四个。整个世界都是这样的,你不想因为你喜欢三个空格的布局而成为局外人。

总结

在这一章中,我们开始探索编程和 Python 的世界。我们只是初步了解了一点点,涉及到的概念将在本书的后面更详细地讨论。

我们谈到了 Python 的主要特性,谁在使用它以及为什么,以及我们可以用哪些不同的方式编写 Python 程序。

在本章的最后部分,我们简要介绍了命名空间、作用域、类和对象的基本概念。我们还看到了 Python 代码如何使用模块和包进行组织。

在实际操作中,我们学会了如何在系统上安装 Python,如何确保我们拥有所需的工具pip和 virtualenv,并创建并激活了我们的第一个虚拟环境。这将使我们能够在一个独立的环境中工作,而不会危及 Python 系统的安装。

现在你已经准备好和我一起开始这段旅程了。你所需要的只是热情、激活的虚拟环境、这本书、你的手指和一些咖啡。

尝试跟着例子走;我会让它们简单而简短。如果你能熟练掌握它们,你会比仅仅阅读更好地记住它们。

在下一章中,我们将探索 Python 丰富的内置数据类型。有很多内容需要涵盖和学习!

第二章:内置数据类型

“数据!数据!数据!”他不耐烦地喊道。“没有黏土,我无法制砖。”– 福尔摩斯 – 铜山丛林的冒险

您使用计算机的一切都是在管理数据。数据有许多不同的形状和口味。这是您听的音乐,您流媒体的电影,您打开的 PDF。甚至您正在阅读的本章的来源只是一个文件,即数据。

数据可以是简单的,用整数表示年龄,也可以是复杂的,比如在网站上下的订单。它可以是关于单个对象或关于它们的集合。数据甚至可以是关于数据,即元数据。描述其他数据结构的设计或描述应用程序数据或其上下文的数据。在 Python 中,对象是数据的抽象,Python 有各种各样的数据结构,您可以使用它们来表示数据,或者将它们组合起来创建自己的自定义数据。

在本章中,我们将涵盖以下内容:

  • Python 对象的结构
  • 可变性和不可变性
  • 内置数据类型:数字、字符串、序列、集合和映射类型
  • 集合模块
  • 枚举

一切皆为对象

在我们深入具体内容之前,我希望您对 Python 中的对象非常清楚,所以让我们再多谈谈它们。正如我们已经说过的,Python 中的一切都是对象。但是当您在 Python 模块中键入age = 42这样的指令时,实际上发生了什么?

如果您转到pythontutor.com/,您可以在文本框中键入该指令并获得其可视化表示。记住这个网站;它对于巩固您对幕后发生的事情的理解非常有用。

因此,创建了一个对象。它获得了idtype设置为int(整数),value设置为42。一个名为age的名称被放置在全局命名空间中,指向该对象。因此,每当我们在全局命名空间中,在执行该行之后,我们可以通过简单地通过其名称访问它来检索该对象:age

如果你要搬家,你会把所有的刀、叉和勺子放在一个箱子里,贴上标签餐具。你能看到这完全是相同的概念吗?这是一个可能看起来像的屏幕截图(你可能需要调整设置以获得相同的视图):


因此,在本章的其余部分,每当您读到诸如name = some_value之类的内容时,都要想象一个放置在命名空间中并与编写该指令的范围相关联的名称,指向具有idtypevalue的对象的漂亮箭头。关于这个机制还有一些要说的地方,但是通过一个例子来谈论它要容易得多,所以我们稍后会回到这个问题。

可变还是不可变?这是个问题

Python 对数据做出的第一个基本区分是关于对象的值是否会改变。如果值可以改变,则对象称为可变,而如果值不能改变,则对象称为不可变

非常重要的是,您理解可变和不可变之间的区别,因为它会影响您编写的代码,所以这里有一个问题:

>>> age = 42
>>> age
42
>>> age = 43  #A
>>> age
43

在前面的代码中,在#A行,我改变了年龄的值吗?嗯,没有。但现在是43(我听到你说…)。是的,是43,但42是一个整数,类型为int,是不可变的。所以,真正发生的是,在第一行,age是一个名称,它被设置为指向一个int对象,其值为42。当我们键入age = 43时,发生的是创建另一个对象,类型为int,值为43(另外,id将不同),并且名称age被设置为指向它。因此,我们没有将42更改为43。实际上,我们只是将age指向了一个不同的位置:值为43的新int对象。让我们看看相同的代码也打印出 ID:

>>> age = 42
>>> id(age)
4377553168
>>> age = 43
>>> id(age)
4377553200

请注意,我们通过调用内置的id函数打印 ID。如你所见,它们是不同的,正如预期的那样。请记住,age一次只指向一个对象:首先是42,然后是43。从不同时。

现在,让我们看一个使用可变对象的相同示例。对于这个示例,让我们只使用一个Person对象,该对象具有一个age属性(现在不用担心类声明;它只是为了完整性):

>>> class Person():
...     def __init__(self, age):
...         self.age = age
...
>>> fab = Person(age=42)
>>> fab.age
42
>>> id(fab)
4380878496
>>> id(fab.age)
4377553168
>>> fab.age = 25  # I wish!
>>> id(fab)  # will be the same
4380878496
>>> id(fab.age)  # will be different
4377552624

在这种情况下,我设置了一个typePerson(自定义类)的对象fab。在创建时,对象被赋予age42。我打印它,以及对象id,以及age的 ID。请注意,即使我将age更改为25fab的 ID 仍然保持不变(当然,age的 ID 已经改变了)。Python 中的自定义对象是可变的(除非你编码使它们不可变)。记住这个概念;这是非常重要的。我会在本章的其余部分提醒你。

数字

让我们从探索 Python 的内置数字数据类型开始。Python 是由一位数学和计算机科学硕士设计的,所以它对数字有很好的支持是很合理的。

数字是不可变对象。

整数

Python 整数具有无限范围,仅受可用虚拟内存的限制。这意味着实际上并不重要要存储多大的数字:只要它能够适应计算机的内存,Python 就会处理它。整数可以是正数、负数和 0(零)。它们支持所有基本的数学运算,如下例所示:

>>> a = 14
>>> b = 3
>>> a + b  # addition
17
>>> a - b  # subtraction
11
>>> a * b  # multiplication
42
>>> a / b  # true division
4.666666666666667
>>> a // b  # integer division
4
>>> a % b  # modulo operation (reminder of division)
2
>>> a ** b  # power operation
2744

前面的代码应该很容易理解。只要注意一件重要的事情:Python 有两个除法运算符,一个执行所谓的真除法/),它返回操作数的商,另一个是所谓的整数除法//),它返回操作数的向下取整商。值得注意的是,在 Python 2 中,除法运算符/的行为与 Python 3 中不同。看看对于正数和负数是如何不同的:

>>> 7 / 4  # true division
1.75
>>> 7 // 4  # integer division, truncation returns 1
1
>>> -7 / 4  # true division again, result is opposite of previous
-1.75
>>> -7 // 4  # integer div., result not the opposite of previous
-2

这是一个有趣的例子。如果你在最后一行期望得到-1,不要感到难过,这只是 Python 的工作方式。在 Python 中,整数除法的结果总是朝负无穷大方向舍入。如果你想将一个数字截断为整数,而不是向下取整,你可以使用内置的int函数,如下例所示:

>>> int(1.75)
1
>>> int(-1.75)
-1

注意截断是朝0方向进行的。

还有一个运算符可以计算除法的余数。它被称为模运算符,用百分号(%)表示:

>>> 10 % 3  # remainder of the division 10 // 3
1
>>> 10 % 4  # remainder of the division 10 // 4
2

Python 3.6 中引入的一个很好的特性是能够在数字文字中添加下划线(在数字或基数说明符之间,但不能在前导或尾随)。其目的是帮助使一些数字更易读,例如1_000_000_000

>>> n = 1_024
>>> n
1024
>>> hex_n = 0x_4_0_0  # 0x400 == 1024
>>> hex_n
1024 

布尔值

布尔代数是代数的一个子集,在其中变量的值是真值:真和假。在 Python 中,TrueFalse是两个关键字,用于表示真值。布尔值是整数的一个子类,分别像10一样行为。布尔值的等价int类是bool类,它返回TrueFalse。在布尔上下文中,每个内置的 Python 对象都有一个值,这意味着当它们被传递给bool函数时,它们基本上会评估为TrueFalse。我们将在第三章中详细了解这一切,迭代和做决定

布尔值可以使用逻辑运算符andornot在布尔表达式中组合。再次,我们将在下一章中全面了解它们,所以现在让我们只看一个简单的例子:

>>> int(True)  # True behaves like 1
1
>>> int(False)  # False behaves like 0
0
>>> bool(1)  # 1 evaluates to True in a boolean context
True
>>> bool(-42)  # and so does every non-zero number
True
>>> bool(0)  # 0 evaluates to False
False
>>> # quick peak at the operators (and, or, not)
>>> not True
False
>>> not False
True
>>> True and True
True
>>> False or True
True

当你尝试将TrueFalse相加时,你会发现它们是整数的子类。Python 将它们向上转换为整数并执行加法:

>>> 1 + True
2
>>> False + 42
42
>>> 7 - True
6 

Upcasting是一种从子类到其父类的类型转换操作。在这里呈现的例子中,TrueFalse属于从整数类派生的类,当需要时会转换回整数。

Python 入门指南(一)(3)https://developer.aliyun.com/article/1507358

相关文章
|
4天前
|
数据采集 机器学习/深度学习 人工智能
Python编程入门:从零基础到实战应用
【9月更文挑战第15天】本文将引导读者从零开始学习Python编程,通过简单易懂的语言和实例,帮助初学者掌握Python的基本语法和常用库,最终实现一个简单的实战项目。文章结构清晰,分为基础知识、进阶技巧和实战应用三个部分,逐步深入,让读者在学习过程中不断积累经验,提高编程能力。
|
3天前
|
开发框架 缓存 数据库
探索Python中的装饰器:从入门到实践
【8月更文挑战第48天】本文将引导你进入Python装饰器的奇妙世界。不同于传统的“摘要”格式,我们将通过一段代码的演变,直观展示装饰器的魅力。文章不仅介绍基础概念,还将通过实例演示如何自定义装饰器,并探讨其在实际应用中的强大用途。让我们开始吧,一起深入理解这个改变函数行为的强大工具!
|
1天前
|
人工智能 数据挖掘 开发者
Python编程入门:从基础到实战
【9月更文挑战第18天】本文将带你走进Python的世界,从最基本的语法开始,逐步深入到实际的项目应用。无论你是编程新手,还是有一定基础的开发者,都能在这篇文章中找到你需要的内容。我们将通过详细的代码示例和清晰的解释,让你轻松掌握Python编程。
15 5
|
3天前
|
Python
全网最适合入门的面向对象编程教程:Python函数方法与接口-函数与方法的区别和lamda匿名函数
【9月更文挑战第15天】在 Python 中,函数与方法有所区别:函数是独立的代码块,可通过函数名直接调用,不依赖特定类或对象;方法则是与类或对象关联的函数,通常在类内部定义并通过对象调用。Lambda 函数是一种简洁的匿名函数定义方式,常用于简单的操作或作为其他函数的参数。根据需求,可选择使用函数、方法或 lambda 函数来实现代码逻辑。
|
3天前
|
存储 机器学习/深度学习 数据挖掘
深入浅出:Python编程入门与实践
【9月更文挑战第16天】本文以“深入浅出”的方式,引领读者步入Python编程的世界。从基础语法到实际应用,我们将一步步探索Python的魅力所在。无论你是编程新手,还是希望拓展技能的老手,这篇文章都将为你提供有价值的信息和指导。通过本文的学习,你将能够编写出简单而实用的Python程序,为进一步深入学习打下坚实的基础。让我们一起开始这段编程之旅吧!
|
9天前
|
存储 人工智能 数据挖掘
Python编程入门:从基础到实战
【9月更文挑战第10天】本文将引导你进入Python编程的世界,从基本语法到实际项目应用,逐步深入。我们将通过简单的例子和代码片段,帮助你理解并掌握Python编程的精髓。无论你是编程新手还是有一定经验的开发者,都能在这篇文章中找到有价值的信息。让我们一起开始Python编程之旅吧!
|
3天前
|
机器学习/深度学习 数据挖掘 程序员
Python编程基础:从入门到实践
【9月更文挑战第16天】本文是一篇Python编程的入门教程,旨在帮助初学者理解Python的基本概念和语法。文章首先介绍了Python的历史和特点,然后详细讲解了Python的基本语法,包括变量、数据类型、运算符、控制结构等。接着,文章通过一些实例代码,展示了如何使用Python进行基本的编程操作,如输入输出、条件判断、循环等。最后,文章还提供了一些学习资源和建议,帮助读者进一步学习和掌握Python编程。
|
7天前
|
SQL 安全 数据库
从入门到精通:Python Web安全守护指南,SQL注入、XSS、CSRF全防御!
【9月更文挑战第13天】在开发Python Web应用时,安全性至关重要。本文通过问答形式,详细介绍如何防范SQL注入、XSS及CSRF等常见威胁。通过使用参数化查询、HTML转义和CSRF令牌等技术,确保应用安全。附带示例代码,帮助读者从入门到精通Python Web安全。
27 6
|
4天前
|
存储 程序员 开发者
Python 编程入门:从零基础到编写实用脚本
【9月更文挑战第15天】本文是一篇面向初学者的Python编程入门指南,通过浅显易懂的语言和实际的代码示例,引导读者逐步掌握Python的基本概念、语法规则以及如何运用Python解决实际问题。文章不仅介绍了Python的基础知识点,还通过实例演示了如何将这些知识应用于日常编程任务中,帮助读者快速上手并能够独立编写简单的Python脚本。
|
10天前
|
开发者 Python
探索Python中的装饰器:从入门到实践
【8月更文挑战第41天】本文通过深入浅出的方式,引导读者理解Python装饰器的概念、原理及应用。我们将从装饰器的定义出发,逐步深入其背后的工作原理,并通过实际代码示例,展示如何自定义装饰器以及装饰器的高级用法。文章旨在帮助初学者快速掌握装饰器的使用,同时为有一定基础的开发者提供进阶知识。