Python 和 Go:逐步解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Python 和 Go 各具特色,能够互补

Python 和 Go 各具特色,能够互补

有一个常见的误解认为 简单(simple)和 容易(easy)指的是同一件事。毕竟,如果某样东西易于使用,那么其内在机制必须也简单易懂,对吗?或者反之亦然?实际上正好相反。虽然这两个概念精神上指向相同的结果,但让外表看起来容易需要底层极其复杂的设计。

以 Python  为例,这是一种因其入门门槛低而被广泛喜爱的编程语言,因此成为入门编程语言的首选。全球的学校、大学、研究中心以及大量企业选择  Python,正是因为它对任何人都易于接近,无论他们的教育水平或学术背景如何(甚至完全没有)。人们很少需要太多类型理论或理解事物如何及在何处存储在内存中,哪些代码片段在哪个线程上运行等。此外,Python是通向一些最深奥的科学和系统级库的入口。用一行代码控制这么大的能量,足以说明其成为地球上最流行的编程语言之一的优势所在。

但这里存在一个问题 - 用  Python 代码表达事物的便捷性是有代价的。在底层,Python  解释器庞大,即使是执行单行代码也需要进行许多操作。当你听到有人称 Python  为“慢速”语言时,所谓的“慢速”很大程度上来自解释器在运行时做出的决策数量。但在我看来,这甚至不是最大的问题。Python  运行时生态系统的复杂性,加上其包管理周围一些自由的设计决策,构成了一个非常脆弱的环境,更新常会导致不兼容和运行时崩溃。发现一个 Python  应用程序几个月后再回来使用时,仅因宿主环境的足够变化就可能导致应用程序无法启动,这并不罕见。

当然,这是一种严重的简化,甚至现在的孩子都知道容器存在是为了解决这类问题。实际上,多亏了 Docker 及其类似的工具,可以“冻结”  Python  代码库的依赖项,使其实际上可以永远运行。但这是以将责任和复杂性转移到操作系统基础结构为代价的。这不是世界末日,但也不是可以轻视和忽略的事情。

从容易到简单

如果我们要解决 Python 的问题,我们可能会得到像 Rust 这样的东西——极其高效但入门门槛显然很高。在我看来, Rust  既不容易使用,也不简单。虽然现在它非常热门,但尽管我有 20 年的编程经验,从 C 和 C++ 开始,我看着一段 Rust  代码也不能肯定地说我明白其中发生了什么。

大约五年前,当我在处理一个基于 Python 的系统时,我发现了  Go。虽然我尝试了几次才开始喜欢它的语法,但我立刻被简单的理念所吸引。Go  旨在让组织中的任何人都能简单理解——从刚毕业的初级开发者到只偶尔看代码的高级工程经理。更重要的是,作为一种简单的语言,Go  很少更新语法——最后一次重大更新是在 v1.18 版本中添加泛型,这是经过十年的严肃讨论之后的事情。大部分情况下,无论你是看五天前还是五年前写的  Go 代码,它们大致相同,并且应该能正常工作。

简单性需要纪律性。起初,它可能感到限制性,甚至有些落后。特别是与 Python 中的简洁表达相比,比如列表或字典推导式:

temperatures = [
    {"city": "City1", "temp": 19},
    {"city": "City2", "temp": 22},
    {"city": "City3", "temp": 21},
]
filtered_temps = {
    entry["city"]: entry["temp"] for entry in temperatures if entry["temp"] > 20
}

在 Go 中编写相同的代码需要敲击更多的键盘,但理想情况下应该更接近 Python 解释器在底层所做的事情:

type CityTemperature struct {
    City      string
    Temp float64
}
// ...
temperatures := []CityTemperature{
    {"City1", 19},
    {"City2", 22},
    {"City3", 21},
}
filteredTemps := make(map[string]float64)
for _, ct := range temperatures {
    if ct.Temp > 20 {
        filteredTemps[ct.City] = ct.Temp
    }
}

虽然你可以用 Python 编写等效代码,但编程中有一个不成文的规则说,如果语言提供了一个 更简单 (即,更简洁、更优雅)的选项,程序员会倾向于使用它。但容易是主观的,简单应该对每个人都同样适用。执行相同操作的替代方法的可用性导致了不同的编程风格,一个代码库中经常可以发现多种风格。

由于 Go 冗长且“无聊”,它自然满足了另一个条件 - Go 编译器在编译可执行文件时的工作量要少得多。编译并运行 Go  应用程序通常和启动 Python 解释器或 Java  的虚拟机之前的速度一样快,甚至更快。不出所料,作为本地可执行文件的速度是可以做到的最快的。它不像其 C/C++ 或 Rust  对手那样快,但代码复杂性却少了很多。我愿意忽略 Go 的这个小“缺点”。最后但同样重要的是,Go  二进制文件是静态绑定的,意味着你可以在任何地方构建它,并在目标主机上运行——无需任何运行时或库依赖。为了方便起见,我们仍然会将 Go  应用程序包装在 Docker 容器中。不过,这些容器显著更小,并且它们的内存和 CPU 消耗只是 Python 或 Java 对应物的一小部分。

如何将 Python 和 Go 的优势结合起来使用

我们在工作中发现的最实用的解决方案是结合 Python 的 容易 和 Go 的 简单。对我们来说,Python 是一个绝佳的原型设计游乐场。这是思想诞生的地方,科学假设得到接受和拒绝的地方。Python 自然适用于数据科学和机器学习,既然我们要处理大量这类工作,尝试用其他东西重新发明轮子就没什么意义。Python 也是 Django 的核心,这体现了它的口号,即允许快速应用程序开发,这一点很少有其他工具(当然,Ruby on Rails 和 Elixir 的 Phoenix 也值得称赞)能够做到。

假设一个项目需要哪怕是最少量的用户管理和内部数据管理(像我们的大多数项目一样)。在这种情况下,我们会从 Django  框架开始,因为它内置的 Admin 非常棒。一旦粗糙的 Django 概念验证开始类似于一个产品,我们就会确定其中有多少可以用 Go 重写。因为  Django 应用程序已经定义了数据库的结构和数据模型的外观,所以编写在其之上的 Go  代码相当容易。经过几次迭代,我们达到了一种共生状态,其中两边在同一个数据库之上和平共存,并使用基本的消息传递彼此通信。最终,Django  的“外壳”成为了一个协调器——它服务于我们的管理目的,并触发接下来由其 Go 对应物处理的任务。Go 部分处理其他一切,从面向前端的 API  和端点到业务逻辑和后端作业处理。

相关文章
|
14天前
|
算法 Python
Python 大神修炼手册:图的深度优先&广度优先遍历,深入骨髓的解析
在 Python 编程中,掌握图的深度优先遍历(DFS)和广度优先遍历(BFS)是进阶的关键。这两种算法不仅理论重要,还能解决实际问题。本文介绍了图的基本概念、邻接表表示方法,并给出了 DFS 和 BFS 的 Python 实现代码示例,帮助读者深入理解并应用这些算法。
28 2
|
23天前
|
测试技术 开发者 Python
深入浅出:Python中的装饰器解析与应用###
【10月更文挑战第22天】 本文将带你走进Python装饰器的世界,揭示其背后的魔法。我们将一起探索装饰器的定义、工作原理、常见用法以及如何自定义装饰器,让你的代码更加简洁高效。无论你是Python新手还是有一定经验的开发者,相信这篇文章都能为你带来新的启发和收获。 ###
13 1
|
23天前
|
设计模式 测试技术 开发者
Python中的装饰器深度解析
【10月更文挑战第24天】在Python的世界中,装饰器是那些能够为函数或类“添彩”的魔法工具。本文将带你深入理解装饰器的概念、工作原理以及如何自定义装饰器,让你的代码更加优雅和高效。
|
1月前
|
XML 前端开发 数据格式
Beautiful Soup 解析html | python小知识
在数据驱动的时代,网页数据是非常宝贵的资源。很多时候我们需要从网页上提取数据,进行分析和处理。Beautiful Soup 是一个非常流行的 Python 库,可以帮助我们轻松地解析和提取网页中的数据。本文将详细介绍 Beautiful Soup 的基础知识和常用操作,帮助初学者快速入门和精通这一强大的工具。【10月更文挑战第11天】
60 2
|
1月前
|
数据安全/隐私保护 流计算 开发者
python知识点100篇系列(18)-解析m3u8文件的下载视频
【10月更文挑战第6天】m3u8是苹果公司推出的一种视频播放标准,采用UTF-8编码,主要用于记录视频的网络地址。HLS(Http Live Streaming)是苹果公司提出的一种基于HTTP的流媒体传输协议,通过m3u8索引文件按序访问ts文件,实现音视频播放。本文介绍了如何通过浏览器找到m3u8文件,解析m3u8文件获取ts文件地址,下载ts文件并解密(如有必要),最后使用ffmpeg合并ts文件为mp4文件。
|
15天前
|
安全 测试技术 Go
Go语言中的并发编程模型解析####
在当今的软件开发领域,高效的并发处理能力是提升系统性能的关键。本文深入探讨了Go语言独特的并发编程模型——goroutines和channels,通过实例解析其工作原理、优势及最佳实践,旨在为开发者提供实用的Go语言并发编程指南。 ####
|
19天前
|
Go
|
5月前
|
XML JavaScript 关系型数据库
Python XML 解析
Python XML 解析
|
6月前
|
XML JavaScript API
Python XML 解析
Python XML 解析
|
XML JavaScript 关系型数据库
下一篇
无影云桌面