带你读《Python网络编程(原书第2版)》之一:回顾TCP/IP协议簇和Python-阿里云开发者社区

开发者社区> 华章出版社> 正文

带你读《Python网络编程(原书第2版)》之一:回顾TCP/IP协议簇和Python

简介: 本书是一本实用型的基础技术实践工具书,技术性较强,如果你想快速了解计算机网络管理、网络安全、自动化运维、Python Web搭建、网络测试相关的知识,本书很适合你。本书涵盖的知识点主要是网络运维相关技术,在学习完所有的章节之后,读者能对网络的管理有初步的了解。每个章节的后面部分都是有一定难度的扩展资源,循序渐进,帮助读者提升网络运维能力。

华章程序员书库
点击查看第二章
点击查看第三章
Python网络编程(原书第2版)
Mastering Python Networking, Second Edition

image.png

[美] 埃里克·周(Eric Chou)著
熊安萍 邹洋 张璞 李鸿健 等译

第1章

回顾TCP/IP协议簇和Python
欢迎来到网络工程的新时代。在千禧年之际,我作为网络工程师开始工作,这个角色与其他技术角色截然不同。网络工程师利用特定领域的知识,管理和运营局域网和广域网,偶尔也会跨越到系统管理,但不用编写代码或理解编程概念。现在已不再是这种情况。多年来,DevOps和软件定义网络(SDN)以及其他因素大大模糊了网络工程师、系统工程师和开发人员之间的界限。
你拿到这本书意味着你可能已经是网络DevOps的采纳者,或者你正在考虑走这条道路。也许你像我一样做了多年的网络工程师,并想知道Python编程语言为什么这么火。或者你可能已经熟悉Python,但想知道它在网络工程中的应用是什么。如果你属于这些阵营中的任何一个,或者只是对网络工程领域的Python感到好奇,我相信这本书适合你:

image.png

目前市面上已经存在很多深入研究网络工程和Python主题的书籍。在本书中我不想去重复他们的工作。相反,本书假设你具有管理网络的实践经验,并且对网络协议和Python语言有基本了解。你不需要成为Python或网络工程专家,但应该从本章的综述中了解基本概念。本章的其余部分将会设定必要的知识储备等级,以充分利用本书。如果你想了解本章内容,可以使用许多免费或低成本资源来加快速度。这里推荐免费的Khan学院(https://www.khanacademy.org/ )和Python教程(https://www.python.org/ )。
本章将快速访问相关的网络主题。根据我在现场工作的经验,典型的网络工程师或开发人员可能不记得完成日常任务时确切的TCP状态机(我知道我不记得了),却更熟悉OSI模型的基础知识、TCP和UDP操作、不同IP头字段和其他基础概念。
我们还将回顾Python语言的概要,对于那些没有每天使用Python语言的读者来说,足以继续学习本书的其余部分。
特别地,我们会涉及下面的主题:

  • 互联网的概述。
  • OSI和客户端–服务端模型。
  • TCP、UDP和IP协议簇。
  • Python语法、类型、操作符和循环。
  • 用于扩展Python的函数、类和包。

当然,本章提供的信息并非详尽无遗,请查看参考资料以获取更多信息。

1.1 互联网概述

什么是互联网?依据你的背景,对于这个看似简单的问题可能会给出不同的答案。不同的人对互联网有不同的理解,年轻人、老年人、学生、老师、商业人士、诗人对这个问题会给出不同的答案。
对于一个网络工程师而言,互联网是一个由大小网络连接在一起组成的全球计算机网络。换句话说,它是一个没有中心所有者的网络。以你的家庭网络为例,它可以由一个家庭以太网交换机和连接智能手机、平板电脑、计算机以及电视的无线接入点组成,以实现设备间通信。这是你的局域网(LAN)。当你的家庭网络需要与外部世界通信时,它会将信息从LAN传递到更大的网络,通常称为互联网服务提供商(ISP)。你的ISP通常由边缘节点组成,这些边缘节点将流量聚合到其核心网络。核心网络的功能是通过更高速的网络互连这些边缘网络。在特殊的边缘节点,你的ISP已连接到其他ISP,以便将你的流量恰当地传递到目的地。从目标网络到家用计算机、平板电脑或智能手机的返回路径可能会也可能不会通过相同路径返回到你的设备,而来源和目标网络保持不变。
让我们来看看组成这个网络的组件。

1.1.1 服务器、主机和网络组件

主机是网络上与其他节点通信的终端节点。在当今世界,主机可以是传统计算机,也可以是智能手机、平板电脑或电视。随着物联网(IoT)的兴起,主机的广泛定义可以扩展到包括IP摄像机、电视机顶盒,以及我们用于农业、耕作、汽车等不断增加的各种类型的传感器。随着连接到互联网的主机数量激增,所有这些主机都需要进行寻址、路由和管理。对以上这些特有的网络的需求从未如此强烈。
我们上网的大部分时间都是通过请求获取服务。请求的服务可以是浏览网页、发送或接收电子邮件、传输文件等。这些服务由服务器提供,顾名思义,服务器为多个节点提供服务,因此通常具有更高级别的硬件规范。在某种程度上,服务器是网络上的特殊超级节点,为其他节点提供额外的能力。我们稍后将在客户端–服务器模型中看到。
如果你将服务器和主机视为城市和城镇,则网络组件是将它们连接在一起的道路和高速公路。实际上,在描述跨越全球传输不断增加的比特和字节的网络组件时,会想到信息高速公路这一术语。在OSI模型中我们将看到以比特(bit)传输的网络组件,它们是第一层到第三层设备。它们是用于引导流量的第二层和第三层的路由器和交换机,以及诸如光纤电缆、同轴电缆、双绞铜线和一些DWDM设备之类的第一层传输设备,在此仅举几例。
总而言之,主机、服务器和网络组件构成了我们今天所知的互联网。

1.1.2 数据中心的兴起

在上一节中,我们看到了服务器、主机和网络组件在互联网中的不同角色。由于服务器需要更高的硬件能力,它们通常一起放置在一个中央位置,以便有效管理。我们通常将这些中央位置称为数据中心。

1.1.2.1 企业数据中心

在典型的企业中,公司通常需要内部工具,例如电子邮件、文档存储、销售跟踪、订购、HR工具和知识共享内联网。这些服务转换为文件和邮件服务器、数据库服务器和Web服务器。与用户计算机不同,这些通常是需要大量电源、冷却和网络连接的高端计算机。硬件的副作用也是来源于硬件产生的噪声。它们通常位于企业中称为主配线架(MDF)的中心位置,以提供必要的供电、电源冗余、冷却和网络连接。
要连接到MDF,用户的流量在捆绑并连接到MDF之前,用户的通信通常聚合在靠近用户的位置,有时称为中间配线架(IDF)。IDF-MDF分布遵循企业大楼或校园的物理布局并不罕见。例如,每个建筑物楼层可以包含IDF,该IDF聚合到另一层的MDF。如果企业由多个建筑物组成,则可以通过在将建筑物连接到企业数据中心之前组合建筑物的流量来进行进一步的聚合。
企业数据中心一般遵循三层网络设计。这些层是接入层、汇聚层和核心层。接入层类似于每个用户连接的端口,IDF可以被认为是汇聚层,而核心层由到MDF的连接和企业数据中心组成。当然,这是普遍的企业网络,某些网络不会遵循相同的模型。

1.1.2.2 云数据中心

随着云计算、软件以及基础设施服务的兴起,数据中心云提供商的构建是超大规模的。由于它们所容纳的服务器数量很大,它们通常需要比任何企业数据中心更高的电力、冷却、网络速度和供给能力。即使在云提供商数据中心工作多年之后,每次访问云提供商数据中心时,我仍然惊讶于它们的规模。实际上,云数据中心非常庞大且耗电量巨大,因此它们通常靠近发电厂建造,在那里它们可以获得最便宜的电价,而不会在电力运输过程中损失太多能耗。它们的冷却需求非常大,通常构建在一个普遍寒冷的气候下,这样在需要时仅打开门窗就可以保持服务器运行在安全的温度。任何搜索引擎来到像亚马逊、微软、谷歌和Facebook的科学化构建和管理的云数据中心时,都会给你一些惊人的数字:

image.png

在云提供商规模上,它们需要提供的服务通常不具有成本效益,或者不能切实地安装在单个服务器中。它们分布在一组服务器之间,有时跨越许多不同的机架,为所有者提供冗余和灵活性的服务。延迟和冗余需求给网络带来了巨大的压力。互连的数量相当于网络设备的爆炸式增长,这转化为此网络设备需要进行机架设置、配置和管理的次数。典型的网络设计将是一个多级的CLOS网络:

image.png

在某种程度上,数据中心的网络自动化是保证快速和可靠性所必需的。如果我们跟随传统的方式通过终端和命令行接口来管理网络设备,所需的工时数将不允许在合理的时间内有可供使用的服务。这还没有考虑人工重复易于出错、低效和可怕的工程人才的浪费。
云数据中心是我很多年前开始用Python实现网络自动化的地方,自此从未回头。

1.1.2.3 边缘数据中心

如果我们在数据中心层拥有足够的计算能力,为什么要将数据保留在这些数据中心,而不保留到其他地方呢?来自世界各地的客户端的所有连接都可以路由回提供服务的数据中心服务器,就到此为止了吗?答案当然取决于用例。将请求和会话从客户端一直路由到大型数据中心的最大限制是传输中产生的延迟。换句话说,高延迟是网络的瓶颈。延迟永远不会为零:即使同光在真空中传播的速度一样快,它仍然需要时间进行物理传输。在现实世界中,当数据包穿过多个网络时(有时通过海底电缆、慢速卫星链路、3G或4G蜂窝链路或Wi-Fi连接),延迟将远远高于真空中的光。
解决方案?减少最终用户通过的网络数量。在用户接入网络的边缘尽可能更近地连接到用户,并在边缘位置放置足够的资源来为请求服务。让我们花点时间想象你正在构建下一代视频流服务。为了提高客户对平滑流媒体的满意度,你可能希望将视频服务器放置在尽可能靠近客户的位置,要么是在客户的ISP内部,要么非常靠近客户的ISP。此外,视频服务器集群的上游不是仅连接到一个或两个ISP,而是连接到所有ISP以减少跳数。所有连接都将具有所需的带宽,以减少高峰时段的延迟。这种需求助长了大型ISP的边缘数据中心与内容提供商的对等交换。即使网络设备的数量不如云数据中心那么多,它们也能得益于网络自动化带来的增强的可靠性、安全性和可视性。
我们将在本书后面的章节中介绍安全性和可视性。

1.2 OSI模型

没有首先回顾开放系统互连(OSI)模型的网络书籍是不完整的。该模型是一个概念模型,将电信功能组件化为不同的层。该模型定义了7层,每层独立地位于另一层之上,只要它们遵循定义的结构和特征即可。例如,在网络层中,IP可以位于不同类型的数据链路层(例如以太网或帧中继)之上。OSI参考模型是将不同和多样化技术标准化为人们能够认同的一套通用语言的好方法。这大大减少了各方在特定层的工作范围,并允许他们深入查看特定任务,而不必过多担心兼容性:

image.png

OSI模型最初是在20世纪70年代后期开展的,后来由国际标准化组织(ISO)和现在称为国际电信联盟(ITU-T)的电信标准化部门联合出版。该模型被广泛接受并通常在引入电信领域的新话题时被提及。
在OSI模型开发的同一时期,互联网正在形成。原始设计者使用的参考模型通常指的是TCP/IP模型。传输控制协议(TCP)和互联网协议(IP)是设计中包含的原始协议簇。这有点类似于OSI模型,因为它们将端到端数据通信划分为抽象层。不同的是,模型在应用层中组合了OSI模型的第5~7层,而物理层和数据链路层在链路层中组合在一起:

image.png

OSI和TCP/IP模型都可用于为端到端数据通信提供标准。但是,在大多数情况下,我们更多指的是TCP/IP模型,因为这是互联网的基础。我们将在需要时指定OSI模型,例如在接下来的章节中讨论Web框架时。

1.3 客户端–服务器模型

参考模型演示了数据在两个节点之间进行通信的标准方法。当然,到目前为止,我们都知道并非所有节点都是相同的。即使在DARPA网络时代,也有工作站节点,并且有些节点的目的是向其他节点提供内容。这些服务器节点通常具有更高的硬件规格,并由工程师更密切地管理。由于这些节点向其他节点提供资源和服务,因此通常称它们为服务器。服务器通常处于空闲状态,等待客户端发起对其资源的请求。客户端请求的分布式资源模型称为客户端–服务器模型。
为什么这很重要?如果你思考一下,客户端–服务器模型突出显示了网络的重要性。如果没有它,那么对网络互连的需求就没有那么大。需要从客户端向服务器传输位和字节,这显示了网络工程的重要性。当然,我们都知道它们中最大的网络—互联网,是如何持续改变我们所有人的生活。
如果你问每个节点在每次相互通信时如何确定时间、速度、来源和目的地,这些问题将涉及接下来的网络协议。

1.4 网络协议簇

在计算机网络的早期阶段,协议是专有的,并由设计连接方法的公司严密控制。如果你在主机中使用Novell的IPX/SPX协议,你就无法与Apple的AppleTalk主机进行通信,反之亦然。这些专有协议簇通常具有与OSI参考模型类似的层,并遵循客户端–服务器通信方法。它们通常在封闭的局域网(LAN)中工作得很好,而不需要与外界通信。当数据流确实需要超出本地LAN时,通常使用互联网工作设备(如路由器)将一种协议转换为另一种协议。比如将AppleTalk网络连接到基于IP的网络的路由器。这种转换通常并不完美,但由于在早期大多数通信发生在LAN内,所以没关系。
然而,随着对网络间通信的需求超越LAN,标准化网络协议簇的需求变得更大。专有协议最终被TCP、UDP和IP的标准化协议取代,这大大提高了网络间通信的能力。互联网是其中最大的网络,它依赖于这些协议才能维持正常功能。在接下来的几节中,我们将介绍每个协议簇。

1.4.1 传输控制协议

传输控制协议(TCP)是当今互联网上使用的主要协议之一。如果你打开了一个网页或发送电子邮件,你就使用了TCP。该协议位于OSI模型的第4层,它负责以可靠的和错误检查的方式在两个节点之间传递数据段。TCP由160位头部组成,其中包括源端口和目标端口、序列号、确认号、控制标志和校验和:

image.png

1.4.1.1 TCP的功能和特点

TCP使用数据报套接字或端口来建立主机到主机的通信。互联网号码分配委员会(IANA)是为常用的端口指定确定服务的标准机构,例如端口80提供HTTP(Web)服务,端口25提供SMTP(邮件)服务。客户端–服务器模型中的服务器通常监听这些常用的端口,以便从客户端接收通信请求。TCP连接由操作系统通过表示连接的本地端点套接字管理。
协议操作由状态机组成,其中在通信会话期间,当监听一个输入连接时机器需要进行跟踪,并且在连接关闭后释放资源。每个TCP连接都经历一系列状态,例如Listen、SYN-SENT、SYN-RECEIVED、ESTABLISHED、FIN-WAIT、CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT和CLOSED。

1.4.1.2 TCP消息和数据传输

与处于同一层上的用户数据报协议(UDP)相比TCP最大的区别在于,它以有序和可靠的方式传输数据。由于操作保证传递,通常称TCP为面向连接的协议。它首先通过建立三次握手来同步发送器和接收器、SYN、SYN-ACK和ACK之间的序列号来实现这一点。
确认用于跟踪对话中的后续段。最后,在对话结束时,一方将发送FIN消息,另一方将确认FIN消息以及发送自己的FIN消息。然后,FIN发起方将确认它收到的FIN消息。
正如许多解决TCP连接故障的人告诉你的那样,操作会变得非常复杂。可以确定的是,通常这些操作只是在后台默默地进行。
仅是TCP就可以写一整本书,事实上,有许多关于协议的优秀的书籍。
警告:由于本节是一个快速概述,如果感兴趣,TCP/IP指南(http://www.tcpipguide.com/ )是一个很好的免费资源,你可以用它来深入研究该主题。

1.4.2 用户数据报协议

用户数据报协议(UDP)也是互联网协议簇的核心成员。与TCP一样,它位于OSI模型的第4层,该模型负责在应用层和IP层之间传递数据段。与TCP不同,UDP头部仅有64位,仅包含源和目标端口、长度和校验和。轻量级头部使其非常适合快速数据传输而无须在两台主机之间设置会话,也不需要可靠数据传输。也许今天快速的互联网连接很难想象,但额外的头部对X.21和帧中继链接的早期传输速度产生了很大的影响。虽然与速度差异一样重要,但不必维护各种状态(如TCP),也可以节省两个端点上的计算机资源:

image.png

你现在可能想知道为什么UDP在当今时代曾被使用过,鉴于缺乏可靠的传输,我们不希望所有连接都可靠且无差错吗?如果你考虑多媒体视频流或Skype呼叫,这些应用程序只想尽快传送数据报,就需要较轻的头部。你还可以考虑基于UDP的快速DNS查找过程。当你在浏览器上键入的域名被转换为计算机可理解的地址时,用户将受益于轻量级过程,因为这必须在你喜爱的网站向你发送信息之前发生。
同样,本节并没有充分展开UDP这个主题,如果读者有兴趣了解UDP的更多信息,建议读者通过各种资源探讨该主题。

1.4.3 互联网协议

正如网络工程师告诉你的那样,他们在互联网协议(IP)层,这是OSI模型的第3层。IP负责在端节点之间寻址和路由。IP的寻址可能是其最重要的工作。地址空间分为两部分:网络部分和主机部分。子网掩码用于指示网络地址中的哪个部分由网络组成,哪个部分是主机,方法是将网络部分与1匹配,将主机部分与0匹配。IPv4和以后的IPv6都以点分表示法表示地址,例如,192.168.0.1。子网掩码可以采用点分表示法(255.255.255.0),也可以考虑网络位(/24)使用正斜杠表示位数:

image.png

IPv6头部是IPv4的下一代IP头部,具有固定部分和各种扩展头部:

image.png

固定头部部分中的Next Header字段可以指示随后携带附加信息的扩展头部。扩展头部可以包括路由和段信息。尽管协议设计者希望从IPv4迁移到IPv6,但今天的互联网仍然采用IPv4,其中一些服务提供商内部使用IPv6寻址的网络。

1.4.3.1 IP NAT和安全性

网络地址转换(NAT)通常用于将一系列私有IPv4地址转换为公共路由的IPv4地址。但它也可能意味着IPv4到IPv6之间的转换,例如在运营商边缘的网络内部使用IPv6时,当数据包离开网络时需要被转换为IPv4。出于安全原因,有时也使用NAT6到6。
安全性是一个连续的过程,集成了网络的所有方面,包括自动化和Python。本书旨在使用Python来帮助你管理网络,安全性将作为本书后续章节的一部分来解决,例如通过telnet使用SSHv2。我们还将研究如何使用Python和其他工具来获得网络可视化。

1.4.3.2 IP路由概念

在我看来,IP路由是关于让两个端点之间的中间设备基于IP头部在端点之间传输数据包。对于通过互联网的所有通信,数据包将遍历各种中间设备。如上所述,中间设备包括路由器、交换机、光学装置和各种其他装置,这些装置不在网络层和传输层之外进行检查。类似在公路旅行中,你从美国加利福尼亚州的圣地亚哥市到华盛顿州的西雅图市。IP源地址类似于圣地亚哥,目标IP地址可以认为是西雅图。在你的公路旅行中,你将在许多不同的中间景点停留,如洛杉矶、旧金山和波特兰,这些可以认为是源和目标之间的路由器和交换机。
为什么这很重要?在某种程度上,本书是关于管理和优化这些中间设备的。在跨越多个美式足球场大小的大型数据中心时代,对高效、灵活、可靠和具有成本效益的网络管理方式的需求成为公司竞争的重点。在以后的章节中,我们将深入探讨如何使用Python编程来有效地管理网络。

1.5 Python语言概述

简而言之,本书旨在通过Python使我们的网络工程更容易实现。但什么是Python,为什么它是许多DevOps工程师选择的语言?用Python组织执行摘要https://www.python.org/doc/essays/blurb/ )的话来说:
“Python是一种具有动态语义的解释型、面向对象的高级编程语言。它的高级内置数据结构,结合动态类型和动态绑定,使其对快速应用程序开发以及用作脚本或黏合语言将现有组件连接在一起非常有吸引力。Python简单易学的语法可读性强,因此降低了程序维护的成本。”
如果你是个编程新手,那么前面提到的面向对象的动态语义对你来说可能并不重要。但我认为大家都会认同,快速的应用程序开发、简单易学的语法是件好事。Python作为一种解释语言,意味着不需要编译过程,因此大大减少了编写、测试和编辑Python程序的时间。对于简单脚本,如果脚本失败,只需要一个print语句来调试正在进行的操作。使用解释器还意味着Python可以轻松移植到不同类型的操作系统,例如Windows和Linux,并且在一个操作系统上编写的Python程序可以在另一个操作系统上使用。
通过将大型程序分解为简单的可重用对象以及具有函数、模块和包的其他可重用格式,面向对象的性质鼓励代码重用。事实上,所有Python文件都是可以重用或导入另一个Python程序的模块。这使得在工程师之间共享程序变得容易,并鼓励代码重用。Python也有一个开箱即用的工具,这意味着,对于常见的任务,你无须下载任何其他软件包。为了在不使代码过于烦琐的情况下实现所需功能,在安装Python解释器时会安装一组标准库。对于常规任务,例如正则表达式、数学函数和JSON解码,你只需要import语句,解释器就会将这些函数移动到你的程序中。这就是Python语言的杀手级功能之一。
最后,Python代码可以从一个相对较小的脚本开始,只需几行代码,发展成一个完整的系统工程,这对网络工程师来说非常方便。众所周知,网络通常在没有总体规划的情况下有机增长。可以随网络规模的增长而增长的语言非常宝贵。你可能会惊讶地发现,许多尖端公司(使用Python的组织:https://wiki.python.org/moin/OrganizationsUsingPython )将一种被许多人认为是脚本语言的语言用于完整的系统工程。
如果你曾经在一个必须在不同的供应商平台(例如Cisco IOS和Juniper Junos)间进行切换的环境中工作过,你就会知道为了实现相同任务在不同语法和惯用法之间切换是多么痛苦。Python对大型和小型程序足够灵活,不存在这样的上下文切换。
在本章的其余部分,我们将对Python语言进行高层次的介绍,并进行一些复习。如果你已经熟悉基础知识,请快速浏览或跳过本章的其余部分。

1.5.1 Python版本

正如许多读者已经意识到的那样,Python在过去几年里已经从Python 2发展到Python 3。Python 3于2008年发布,遗憾的是,Python 3并不向后兼容Python 2。在2018年中期编写本书的第2版时,Python已经基本上转移到Python 3。最新的Python 2.x版本是2.7,该版本于2010年中期发布。幸运的是,两个版本可以在同一台机器上共存。就个人而言,当我在命令提示符下键入Python时,我使用Python 2作为我的默认解释器,当我需要使用Python 3时,我需要键入Python 3。有关调用Python解释器的更多信息将在下一节中讲述,一个在Ubuntu Linux机器上调用Python 2和Python 3的示例如下:
image.png
由于2.7版本已经过时,现在大多数Python框架支持Python 3。Python 3还具有许多优秀的功能,例如在我们需要优化代码时可以使用异步I/O。除非另有说明,否则本书将使用Python 3作为代码示例。我们还将尝试指出Python 2和Python 3应用时的差异。
如果特别的库或框架更适合Python 2,例如Ansible(请参阅以下信息),我们将会专门指出使用Python 2。
警告:在撰写本书时,Ansible 2.5及更高版本支持Python 3。在2.5版本之前,支持Python 3的版本被认为是技术预览版。鉴于相对较新的可支持性,许多社区模块仍然尚未迁移到Python 3。有关Ansible和Python 3的更多信息,请参阅https://docs.ansible.com/ansible/2.5/dev_guide/developing_python_3.html

1.5.2 操作系统

如前所述,Python是跨平台的。Python程序可以在Windows、Mac和Linux上运行。实际上,当你需要确保跨平台兼容性时需要特别小心,例如处理Windows文件名中反斜杠之间的细微差别。由于本书适用于DevOps、系统和网络工程师,因此Linux是目标受众的首选平台,尤其是在生产环境中。本书中的代码将在Linux Ubuntu 16.06 LTS机器上进行测试。我还将尽力确保代码在Windows和MacOS平台上可同样运行。
操作系统详细信息如下:
image.png

1.5.3 运行一个Python程序

Python程序由解释器执行,这意味着代码被提供给此解释器,由底层操作系统执行并显示结果。目前Python开发社区有几种不同的解释器,例如IronPython和Jython。在本书中,我们将使用当今最常用的Python解释器,即CPython。本书中提到Python时,除非另有说明,否则我们指的都是CPython。
使用Python的一种方法是利用交互式提示。当你想要快速测试一段Python代码或概念而不编写整个程序时将会有用。通常只需键入Python关键字即可实现:
image.png

提示:在Python 3中,print语句是一个函数,因此,它需要括号。在Python 2中,你可以省略括号。
交互模式是Python最有用的功能之一。在交互式shell中,你可以键入任何有效的语句或语句序列,并立即获得返回结果。我通常使用这种方法来探索我不熟悉的功能或库。交互中立即得到满意结果!
警告:在Windows上,如果没有收到Python shell提示符,则在系统搜索路径中可能没有这个程序。最新的Windows Python安装程序提供了一个用于将Python添加到系统路径的复选框,确保选中这个复选框。或者,你可以通过转到“环境设置”手动在路径中添加程序。
但是,运行Python程序的一种更常见的方法是保存Python文件,然后通过解释器运行它。这将使你无须像在交互式shell中那样一遍又一遍地键入相同的语句。Python文件只是常规文本文件,通常以.py扩展名保存。在* Nix世界中,你还可以在顶部添加shebang(#!)行以指定将用于运行文件的解释器。#字符可用于进行注释,并且不被解释器执行。文件helloworld.py具有以下语句:
image.png

这可以按如下方式执行:
image.png

1.5.4 Python内置类型

Python有几种内置于解释器的标准类型:

  • 空:Null对象。
  • 数值:int、long、float、complex和bool(有True和False值int的子类)。
  • 序列:str、列表、元组和整数列表。
  • 映射:dict。
  • 集合:set和frozenset。

1.5.4.1 空类型

None类型表示没有值的对象。在未显式返回任何内容的函数中返回None类型。如果调用者未传入实际值,则None类型也会在函数参数中用于错误输出。

1.5.4.2 数值

Python数字对象基本上是数字。除布尔值外,int、long、float和complex的数值类型都是有符号的,这意味着它们可以是正数或负数。布尔值是整数的子类,它可以是两个值之一:1表示True,0表示False。其余的数值类型由它们如何精确地表示数字来区分,例如,int是具有有限范围的整数,而long是具有无限范围的整数。浮点数是使用机器上的双精度表示(64位)的数字。

1.5.4.3 序列

序列是有序的对象集,其索引为非负整数。在本节和接下来的几节中,我们将使用交互式解释器来说明不同的类型。请随意在自己的电脑上打字。
有时人们会惊讶于string实际上是一种序列类型。但如果仔细观察,字符串就是一系列字符放在一起。字符串由单引号、双引号或三引号括起来。请注意,在以下示例中,引号必须匹配,并且三引号允许字符串跨越不同的行:
image.png

另外两种常用的序列类型是列表和元组。列表是任意对象的序列。可以通过将对象括在方括号中来创建列表。就像字符串一样,列表由从零开始的非零整数索引。通过引用索引号来检索列表的值:
image.png

元组类似于列表,通过将值括在括号中来创建。与列表一样,元组中的值通过引用其索引号来检索。与列表不同,元组中的值创建后无法修改:
image.png

某些操作对所有序列类型都是通用的,例如通过索引返回元素以及切片:
image.png
image.png

警告:请记住,索引从0开始。因此,索引1实际上是序列中的第二个元素。
还有一些常用函数可以应用于序列类型,例如检查元素数量以及最小值和最大值:
image.png

毫无疑问,有各种方法仅适用于字符串。值得注意的是,这些方法不会修改底层字符串数据本身,并始终返回新字符串。如果要使用新值,则需要捕获返回值并将其分配给另一个变量:
image.png

以下是列表的一些常用方法。列表是一个非常有用的结构,它将多个项目放在一起并一次迭代一个项目。例如,我们可以制作一个数据中心主干交换机列表,并通过逐个迭代它们将相同的访问列表应用于所有这些交换机列表。由于列表的值可以在创建后修改(与元组不同),因此当我们继续执行程序时还可以扩展和对比现有列表:
image.png

1.5.4.4 字典

Python提供了一种映射类型,称为字典。字典包含可以通过键索引的对象,这在其他语言中通常被称为关联数组或散列表。如果你使用过其他语言中的任何类字典对象,你将会知道这是一种强大的类型,因为你可以使用人类可读的键来引用该对象。对于试图维护和排除代码故障的人来说,这个键更有意义。字典值中的对象也可以是另一种数据类型,例如列表。你可以使用花括号创建字典:
image.png

1.5.4.5 集合

集合用于包含无序的对象集。与列表和元组不同,集合是无序的,不能用数字编制索引。但是集合有一个有用的突出特点:集合的元素绝不会重复。想象一下,你有一个IP列表,你需要将其放入访问列表中。这个IP列表中唯一的问题是里面有重复值。现在,考虑一下你将使用多少行代码来遍历IP列表以一次一个地排序唯一项目。但是,内置集合类型允许你只用一行代码消除重复的条目。说实话,我不经常使用集合,但是当我需要它时,我总是非常感谢它的存在。创建一个或多个集合后,可以使用并集,交集和差集将它们相互比较:
image.png
image.png

1.5.5 Python操作符

Python有一些你期望的数值运算符,值得注意的是截断除法(//,也称为floor division)将结果截断为整数和浮点并返回整数值。模数(%)运算符返回除法中的余数值:
image.png

还有比较运算符。需要注意用于比较的双等号和用于变量赋值的单个等号:
image.png

我们还可以使用两个公共成员运算符来查看对象是否在序列类型中:
image.png

1.5.6 Python控制流工具

if、else和elif语句控制条件代码执行。正如人们所预料的那样,条件语句的格式如下:
image.png

这里是一个简单的例子。
image.png

while循环将继续执行,直到条件为false,因此如果你不想继续执行(并使进程崩溃),请小心使用此循环:
image.png

for循环适用于任何支持迭代的对象,这意味着所有内置序列类型(如列表、元组和字符串)都可以在for循环中使用。以下for循环中的字母i是一个迭代变量,因此你通常可以在代码上下文中获取有意义的内容:
image.png
image.png

你还可以创建自己的支持迭代器协议的对象,并能够为此对象使用for循环。
构建这样一个对象超出了本章的范围,但这是有用的知识,你可以在https://docs.python.org/3/c-api/iter.html 阅读更多相关信息。

1.5.7 Python函数

大多数情况下,当你发现自己复制并粘贴一些代码时,你应该把它分解成一个自包含的功能块。这种做法允许更好的模块化,更易于维护,并允许代码重用。Python函数使用带有函数名称的def关键字定义,后边跟着函数参数。函数体由要执行的Python语句组成。在函数结束时,你可以选择将值返回给函数调用者,或者默认情况下,如果你没有指定返回值,它将返回None对象:
image.png

我们将在后面的章节中看到更多的函数示例,所以这里有一个简单的例子:
image.png

1.5.8 Python类

Python是一种面向对象编程(OOP)语言。Python创建对象的方式是使用class关键字。Python对象通常是函数(方法)、变量和属性的集合。定义一个类后,你可以创建此类的实例。该类充当后续实例的蓝图。
OOP的主题超出了本章的范围,因此这里有一个router对象定义的简单示例:
image.png
image.png

一旦类定义后,你就可以根据需要创建该类的任意数量的实例:
image.png

当然,Python对象和OOP还有很多内容。我们将在以后的章节中查看更多示例。

1.5.9 Python模块和包

任何Python源文件都可以用作模块,你可以重用在该源文件中定义的任何函数和类。要加载代码,引用模块的文件需要使用import关键字。导入文件时会发生三件事:

  1. 该文件为源文件中定义的对象创建新的命名空间。
  2. 调用者执行模块中包含的所有代码。
  3. 该文件在调用者中创建一个名称,该名称引用正在导入的模块。该名称与模块的名称匹配。
    还记得使用交互式shell定义的subtract()函数吗?要重用该函数,我们可以将它放入名为subtract.py的文件中:

image.png

在subtract.py的同一目录下的文件中,你可以启动Python解释器并导入此函数:
image.png

这是有效的,因为默认情况下,Python将首先搜索可用模块的当前目录。如果你位于其他目录中,则可以使用带有sys.path的sys模块手动添加搜索路径位置。还记得我们前面提到的标准库吗?你猜对了,那些只是用作模块的Python文件。
包允许将模块集合组合在一起。这进一步将Python模块组织为更多命名空间保护,以进一步提高可重用性。通过创建具有要用作命名空间的名称的目录来定义包,然后可以将模块源文件放在该目录下。为了让Python将其识别为Python包,只需在此目录中创建一个__init__.py文件即可。在与subtract.py文件相同的示例中,如果要创建名为math_stuff的目录并创建__init__.py文件:
image.png

你现在引用该模块的方式将需要包含包名称:
image.png

如你所见,模块和包是组织大型代码文件和使Python代码共享更加容易的好方法。

1.6 小结

在本章中,我们介绍了OSI模型并回顾了网络协议簇,例如TCP、UDP和IP。它们用作处理任意两台主机之间的寻址和通信协商的层。这些协议在设计时考虑了可扩展性,并且与其原始设计基本保持不变。考虑到互联网的爆炸性增长,这是一个相当大的成就。
我们还快速回顾了Python语言,包括内置类型、运算符、控制流、函数、类、模块和包。Python是一种功能强大的用于生产环境的语言,易于阅读。这使得该语言成为网络自动化的理想选择。网络工程师可以利用Python从简单的脚本开始,逐步转向其他高级功能。
在第2章中,我们将开始研究如何使用Python以编程方式与网络设备进行交互。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接