Python 进阶指南(编程轻松进阶):三、使用 Black 工具来格式化代码
原文:http://inventwithpython.com/beyond/chapter3.html

代码格式化是将一组规则应用于源代码,从而使得代码风格能够简洁统一。虽然代码格式对解析程序的计算机来说不重要,但代码格式对于可读性是至关重要的,这是维护代码所必需的条件。如果你的代码对人(无论是你还是同事)来说都很难理解,那么就很难修复错误或添加新功能。格式化代码不仅仅是一个风格的问题。并且 Python 的可读性也是该语言受欢迎的一个重要原因。
本章向您介绍 Black,它是一个代码格式化工具,可以自动将您的源代码格式化成一致的、可读的样式,而不改变您的程序的功能。Black 很有用,因为在文本编辑器或 IDE 中手动格式化代码很繁琐。您将首先了解使用 Black 格式化代码的合理性。然后,您将学习如何安装、使用和定制该工具。
如何失去朋友和疏远同事
我们可以用多种方式编写代码,产生相同的行为。例如,我们可以编写一个列表,在每个逗号后加一个空格,并始终使用一种引用字符:
spam = ['dog', 'cat', 'moose']
但是,即使我们用不同数量的空格和不同的引号样式编写列表,这在语法上仍然是有效的 Python 代码:
spam= [ 'dog' ,'cat',"moose"]
喜欢前一种方法的程序员可能喜欢空格添加的视觉分隔和引号字符的一致性。但程序员有时会选择后者,因为他们这要保证程序功能正确即可,代码可读性的细节不做过度考虑。
初学者经常忽略代码格式,因为他们专注于编程概念和语言语法。但是对于初学者来说,建立良好的代码格式化习惯是很有价值的。编程已经够难的了,给别人(或者以后给自己)写可以理解的代码,在分析代码问题时就不会因为可读性而头疼了。
尽管您可能需要独自编写代码,但编程通常是一项协作活动。如果几个程序员在同一个源代码文件上工作,用他们自己的风格编写,代码可能会变得不一致,混乱不堪,即使它运行时没有错误。或者更糟的是,程序员会不断地将彼此的代码重新格式化成他们自己的风格,浪费时间并引起争论。比如说,决定在逗号后面加一个还是零个空格是个人喜好的问题。这些代码风格选择很像决定在道路的哪一边行驶;人们是在路的右边还是左边开车并不重要,重要的是大家都要习惯于在同一边开车。
风格指南和 PEP8
编写可读代码的一个简单方法是遵循风格指南,这是一个概述了一套软件项目应该遵循的格式规则的文档。由 Python 核心开发团队编写的 Python 增强提案 8(PEP8)就是这样一个风格指南。但是一些软件公司也建立了他们自己的风格指南。
你可以在www.python.org/dev/peps/pep-0008在线阅读 PEP8。许多 Python 程序员将 PEP8 视为一组权威的规则,尽管 PEP8 的创建者们不这么认为。指南的“愚蠢的一致性是心胸狭窄的妖怪”一节提醒读者,保持项目中的一致性和可读性,而不是遵守任何个人的格式规则,是编写这个格式指南的主要原因。
PEP8 甚至包括以下建议:“知道什么时候不一致——有时风格指南的建议并不适用。如有疑问,请做出最佳判断。”无论您是全部遵循、部分遵循还是一点都不遵循,都值得阅读 PEP8 文档。
因为我们使用了 Black 来格式化代码程序,所以我们的代码将遵循 Black 的样式指南,该指南改编自 PEP8 的样式指南。您应该学习这些代码格式指南,因为您在某些特殊环境下编码的时候可能不能使用Black来格式化代码。您在本章中学习的 Python 代码指南通常也适用于其他语言,这些语言可能没有可用的自动格式化程序。
我并不喜欢 Black 的所有代码格式,但我认为这是一个很好的妥协。Black 使用程序员可以忍受的格式规则,让我们花更少的时间争论,花更多的时间编程。
水平间距
空白对于可读性来说和你写的代码一样重要。这些空格有助于将代码的不同部分彼此分开,使它们更容易识别。本节解释了水平间距——即单行代码中空白间隔,包括该行前面的缩进大小。
使用空格字符的缩进
缩进是代码行开头的空格。您可以使用两个空白字符(空格或制表符)中的一个来缩进代码。尽管这两种字符都有效,但最佳实践是使用空格而不是制表符进行缩进。
原因是这两种方式的行为方式不同。一个空格字符总是在屏幕上呈现为带有一个空格的字符串值,就像这个' '。但是制表符,即包含转义字符或'\t'的字符串值,更不明确。制表符通常(但不总是)呈现为可变的间距量,因此下面的文本从下一个制表位开始。在文本文件的宽度上,制表位代表八个空格符。您可以在下面的交互式 Shell 示例中看到这种变化,该示例首先用空格字符分隔单词,然后用制表符分隔单词:
>>> print('Hello there, friend!\nHow are you?')
Hello there, friend!
How are you?
>>> print('Hello\tthere,\tfriend!\nHow\tare\tyou?')
Hello there, friend!
How are you?
因为制表符代表不同宽度的空白,你应该避免在你的源代码中使用它们。当你按下Tab键键而不是一个制表符时,大多数代码编辑器和 ide 会自动插入四或八个空格字符。
你也不能在同一个代码块中使用制表符和空格来缩进。在早期的 Python 程序中,使用两者进行缩进是一个错误的万恶之源,以至于 Python3 甚至不会运行带有缩进的代码;而是引发一个TabError: inconsistent use of tabs and spaces in indentation异常。Black 会自动将您用于缩进的任何制表符转换为四个空格字符。
至于每一级缩进的长度,Python 代码中通常的做法是每一级缩进四个空格。以下示例中的空格字符用句号标记空格,以使其可见:
def getCatAmount():
....numCats = input('How many cats do you have?')....if int(numCats) < 6:........print('You should get more cats.')
与备选方案相比,四个空格的标准有实际的好处;在每一级缩进中使用八个空格会导致代码很快超出行长度限制,而在每一级缩进中使用两个空格会使缩进中的差异难以看出。程序员通常不会考虑其他数量,比如三个或六个空格,因为他们和一般的二进制计算一样,首选二的幂:2、4、8、16 等等。
行内间距
水平间距不仅仅是缩进。空格对于让程序员在视觉上对代码进行分块是很重要的。如果您从不使用空格字符调整间距,那么您的行可能会变得密集而难以解析。以下小节提供了一些需要遵循的间距规则。
在操作符和标识符之间加一个空格
如果你不在操作符和标识符之间留空格,你的代码看起来会一起运行。例如,这一行用空格分隔运算符和变量:
blanks = blanks[:i] + secretWord[i] + blanks[i + 1 :] # YES
这一行删除所有空格:
$1 # NOblanks=blanks[:i]+secretWord[i]+blanks[i+1:]
在这两种情况下,代码都使用了+操作符将三个值相加,但是如果没有空格,blanks[i+1:]中的+看起来像是在添加第四个值。空格使得这个+是blanks中值的一部分变得更加明显。
分隔符前不加空格,分隔符后加一个空格
我们用逗号分隔条目列表和字典,以及函数def语句中的参数。您不应在这些逗号前放置空格,而应在逗号后放置一个空格,如下例所示:
def spam(eggs, bacon, ham): # YESweights = [42.0, 3.1415, 2.718] # YES
否则,您最终会得到更难阅读的“搅合”代码:
$1 # NOdef spam(eggs,bacon,ham):
$1 # NO weights = [42.0,3.1415,2.718]
不要在分隔符前添加空格,因为不要将注意力放在分隔符上:
$1 # NOdef spam(eggs , bacon , ham):
$1 # NO weights = [42.0 , 3.1415 , 2.718]
Black 会自动在逗号后面插入一个空格,并删除逗号前面的空格。
不要在句号之前或之后加空格
Python 允许您在标记 Python 属性开头的点号前后插入空格,但您应该避免这样做。通过不在那里放置空格,可以强调对象与其属性之间的联系,如下例所示:
'Hello, world'.upper() # YES
如果您在句号之前或之后添加空格,对象和属性看起来就像彼此无关:
$1 # NO'Hello, world' . upper()
Black 会自动删除句号周围的空格。
不要在函数、方法或容器名后加空格
我们很容易识别函数和方法名,因为它们后面有一组括号,所以不要在名字和左括号之间加空格。我们通常会编写这样的函数调用:
print('Hello, world!') # YES
但是添加一个空格会使这个函数调用看起来像是在做两件不同的事情:
$1 # NOprint ('Hello, world!')
Black 删除函数或方法名与其左括号之间的任何空格。
同样,不要在索引、切片或键的方括号前加空格。我们通常访问容器类型(如列表、字典或元组)中的项,而不在变量名和左方括号之间添加空格,如下所示:
spam[2] # YES
spam[0:3] # YES
pet['name'] # YES
再次添加空格会使代码看起来像两个独立的东西:
$1 # NOspam [2]
$1 # NOspam [0:3]
$1 # NOpet ['name']
Black 删除变量名和左方括号之间的任何空格。
不要在左括号后或右括号前加空格
圆括号、方括号或大括号及其内容之间不应有空格。例如,def语句中的参数或列表中的值应该紧接在圆括号和方括号的前后开始和结束:
def spam(eggs, bacon, ham): # YESweights = [42.0, 3.1415, 2.718] # YES
不应在左括号或右括号或方括号之后或之前添加空格:
$1 # NOdef spam( eggs, bacon, ham ):
$1 # NO weights = [ 42.0, 3.1415, 2.718 ]
添加这些空格不会提高代码的可读性,所以没有必要。如果代码中存在这些空格,Black 将删除它们。
在行尾注释前加两个空格
如果您在代码行的末尾添加注释,请在代码的末尾和开始注释的#字符之前添加两个空格:
print('Hello, world!') # Display a greeting. # YES
这两个空格使得区分代码和注释更加容易。一个空格,或者更糟的是,没有空格,会使人更难注意到代码和注释的分离:
$1 # NOprint('Hello, world!') # Display a greeting.
$1 # NOprint('Hello, world!')# Display a greeting.
Black 在代码的结尾和注释的开头之间加了两个空格。
一般来说,我建议不要把注释放在代码行的末尾,因为它们会使代码行太长而无法在屏幕上阅读。
垂直间距
垂直间距是代码行之间空白行的位置。就像书中的新段落可以防止句子形成文本墙一样,垂直间距可以将某些代码行组合在一起,并将这些组彼此分开。
PEP8 有几个在代码中插入空行的准则:它规定你应该用两个空行分隔函数,用两个空行分隔类,用一个空行分隔类内的方法。Black 通过在代码中插入或删除空行来自动遵循这些规则,将代码:
$1 # NOclass ExampleClass:def exampleMethod1():passdef exampleMethod2():passdef exampleFunction():pass
。。。到这段代码中:
class ExampleClass: # YESdef exampleMethod1():passdef exampleMethod2():passdef exampleFunction():pass
垂直间距示例
Black 不能做的是决定你的函数、方法或全局范围内的空行应该在哪里。将那些行组合在一起是程序员的主观决定。
例如,让我们看看 Django Web 应用框架中的validators.py中的EmailValidator类。你没必要去理解这个代码是如何工作的。但是请注意空行是如何将__call__()方法的代码分成四组的:
`--snip--`def __call__(self, value):1 if not value or '@' not in value:raise ValidationError(self.message, code=self.code)2 user_part, domain_part = value.rsplit('@', 1)3 if not self.user_regex.match(user_part):raise ValidationError(self.message, code=self.code)4 if (domain_part not in self.domain_whitelist andnot self.validate_domain_part(domain_part)):# Try for possible IDN domain-parttry:domain_part = punycode(domain_part)except UnicodeError:passelse:if self.validate_domain_part(domain_part):returnraise ValidationError(self.message, code=self.code)
`--snip--`
尽管没有注释来描述这部分代码,但是空白行表明这些组在概念上是不同的。第一组 1 检查value参数中的@符号。这个任务与第二组 2 的任务不同,第二组将value中的电子邮件地址字符串拆分成两个新变量user_part和domain_part。第三组 3 和第四组 4 分别使用这些变量来验证电子邮件地址的用户和域两个部分是否合法。
虽然第四组有 11 行,远远多于其他组,但它们都是验证电子邮件地址域的任务。如果您认为该任务确实由多个子任务组成,您可以插入空行来分隔它们。
Django 这一部分的程序员决定域验证行应该都属于一个组,但是其他程序员可能不同意。因为这是主观的,所以 Black 不会修改函数或方法中的垂直间距。
垂直间距最佳实践
Python 的一个鲜为人知的特性是,可以使用分号在一行中分隔多个语句。这意味着下面两行:
print('What is your name?')
name = input()
。。。如果用分号隔开,可以写在同一行上:
print('What is your name?'); name = input()
就像使用逗号一样,分号前不要加空格,分号后加一个空格。
对于以冒号结尾的语句,如if、while、for、def或class语句,使用单行块,如本例中对print()的调用:
if name == 'Alice':print('Hello, Alice!')
。。。可以和它的if语句写在同一行:
if name == 'Alice': print('Hello, Alice!')
但是仅仅因为 Python 允许在同一行中包含多个语句并不意味着这是一个好的示例。这会导致代码行太宽,一行代码中的内容太多。Black 将这些语句拆分成单独的行。
类似地,您可以用一条import语句导入多个模块:
import math, os, sys
即便如此,PEP8 建议您将该语句拆分为每个模块一个import语句:
import math
import os
import sys
如果您为导入模块编写单独的行,当您在使用版本控制系统的差异工具中比较更改时,您将更容易发现导入模块的变动。(版本控制系统,如 Git,将在第 12 章中介绍。)
PEP8 还建议将import语句按以下顺序分成三组:
- Python 标准库中的模块,如
math、os和sys - 第三方模块,如 Selenium、Requests 或 Django
- 作为程序一部分的本地模块
这些准则是可选的,Black 不会改变代码的import语句的格式。
Black:不妥协的代码格式化程序
Black 会自动格式化您的的代码.py文件。虽然你应该理解本章中的格式规则,但是 Black 可以为你做所有定制的样式。如果你正在和其他人一起做一个编码项目,你可以通过自定义 Black 格式化代码风格来降低和其他人的沟通成本。
你不能改变 Black 遵循的许多规则,这就是为什么它被描述为“不妥协的代码格式化程序”事实上,这个工具的名字来源于亨利·福特关于他提供给顾客的汽车颜色选择的名言:“你可以要任何你想要的颜色,只要是 Black 的。”
我刚刚描述了 Black 使用的确切风格;你可以在black.readthedocs.io/en/stable/the_black_code_style找到布莱克的完整风格指南。
安装 Black
使用 Python 自带的pip工具安装 Black。在 Windows 中,通过打开命令提示符窗口并输入以下内容来完成此操作:
C:\Users\Al\>python -m pip install --user black
在 MacOS 和 Linux 上,打开一个终端窗口,输入python3而不是python(本书中所有使用python的指令都应该这样做):
Als-MacBook-Pro:~ al$ python3 -m pip install --user black
-m选项告诉 Python 将pip模块作为应用运行,一些 Python 模块就是这样设置的。通过运行python -m black测试安装是否成功。你应该看到消息No paths given. Nothing to do.而不是No module named black.
从命令行运行 Black
您可以从命令提示符或终端窗口对任何 Python 文件运行 Black。此外,您的 IDE 或代码编辑器可以在后台运行 Black。你可以在布莱克的主页github/psf/black上找到让 Black 使用 Jupyter Notebook、Visual Studio Code、PyCharm 和其他编辑器的说明。
假设您想要自动格式化一个名为yourScript.py的文件。在 Windows 的命令行中,运行以下命令(在 MacOS 和 Linux 上,使用python3命令而不是python
):
C:\Users\Al>python -m black yourScript.py
运行该命令后,yourScript.py的内容将根据 Black 的样式指南进行格式化。
您的PATH环境变量可能已经设置为直接运行 Black,在这种情况下,您只需输入以下内容即可格式化yourScript.py :
C:\Users\Al>black yourScript.py
如果你想在一个文件夹中所有的.py文件跑一次 Black,指定单个文件夹而不是单个文件。以下 Windows 示例格式化C:\yourPythonFiles文件夹中的每个文件,包括其子文件夹:
C:\Users\Al>python -m black C:\yourPythonFiles
如果您的项目包含多个 Python 文件,并且您不想为每个文件输入命令,则指定文件夹非常有用。
尽管 Black 对如何格式化代码有相当严格的要求,但接下来的三个小节描述了一些你可以改变的选项。要查看 Black 提供的全部选项,请运行python -m black --help。
调整 Black 行长度设置
Python 代码的标准行长度为 80 个字符。80 字符行的历史可以追溯到 20 世纪 20 年代穿孔卡计算时代,当时 IBM 推出了 80 列 12 行的穿孔卡。在接下来的几十年里,打印机、显示器和命令行窗口都保留了 80 列的标准。
但在 21 世纪,高分辨率屏幕可以显示超过 80 个字符宽的文本。较长的行长度可以让您不必垂直滚动来查看文件。较短的行长度可以防止过多的代码挤在一行上,并允许您并排比较两个源代码文件,而不必水平滚动。
Black 使用默认的每行 88 个字符,这是相当随意的,因为它比标准的 80 个字符多 10%。我倾向于使用 120 个字符。例如,要告诉 Black 使用 120 个字符的行长度限制来格式化您的代码,请使用-l 120(这是小写字母L而不是数字 1)在命令行选项。在 Windows 上,该命令如下所示:
C:\Users\Al>python -m black -l 120 yourScript.py
无论您为项目选择什么样的行长度限制,所有的.py文件应该使用相同的限制。
禁用 Black 的双引号字符串设置
Black 自动将代码中的任何字符串字面值从使用单引号更改为双引号,除非字符串包含双引号字符,在这种情况下,它使用单引号。例如,假设yourScript.py包含以下内容:
a = 'Hello'
b = "Hello"
c = 'Al\'s cat, Zophie.'
d = 'Zophie said, "Meow"'
e = "Zophie said, \"Meow\""
f = '''Hello'''
在yourScript.py上运行 Black 会将它格式化成这样:
a = "Hello" # 1
b = "Hello"
c = "Al's cat, Zophie."
d = 'Zophie said, "Meow"' # 2
e = 'Zophie said, "Meow"'
f = """Hello""" # 3
Black 对双引号的偏好使您的 Python 代码看起来类似于用其他编程语言编写的代码,这些语言通常对字符串字面值使用双引号。注意变量a、b和c的字符串使用双引号。变量d的字符串保留其原来的单引号,以避免转义字符串 2 中的任何双引号。注意,对于 Python 的三引号多行字符串 3 ,Black 也使用双引号。
但是如果您希望 Black 保留您编写的字符串字面值,并且不改变使用的引号的类型,那么传递给它-S命令行选项。(注意S是大写的。)例如,在 Windows 中对原始的yourScript.py文件运行 Black 会产生以下输出:
C:\Users\Al>python –m black -S yourScript.py
All done!
1 file left unchanged.
您也可以在同一命令中同时使用-l线长度限制和-S选项来限制引用字符串的转换:
C:\Users\Al>python –m black –l 120 -S yourScript.py
预览 Black 将做出的更改
虽然 Black 不会重命名您的变量或改变您的程序的行为,但是您可能不喜欢 Black 所做的样式改变。如果您想坚持原来的格式,您可以对您的源代码使用版本控制或者维护您自己的备份。或者,您可以通过使用--diff命令行选项运行 Black 来预览 Black 将做出的更改,而不会让它实际更改您的文件。在 Windows 中,它看起来像这样:
C:\Users\Al>python -m black --diff yourScript.py
这个命令以版本控制软件通常使用的diff格式输出差异,但是它通常是可读的。例如,如果yourScript.py包含行weights=[42.0,3.1415,2.718],运行--diff选项将显示以下结果:
C:\Users\Al\>python -m black --diff yourScript.py
--- yourScript.py 2020-12-07 02:04:23.141417 +0000
+++ yourScript.py 2020-12-07 02:08:13.893578 +0000
@@ -1 +1,2 @@
-weights=[42.0,3.1415,2.718]
+weights = [42.0, 3.1415, 2.718]
减号表示 Black 将删除线weights= [42.0,3.1415,2.718]并替换为前缀为加号的线:weights = [42.0, 3.1415, 2.718]。请记住,一旦您运行 Black 来更改您的源代码文件,就没有办法撤销这种更改。在运行 Black 之前,您需要备份源代码或使用版本控制软件,如 Git。
禁用部分代码的 Black
尽管 Black 很棒,但您可能不希望它格式化您代码的某些部分。例如,每当我排列多个相关的赋值语句时,我都喜欢使用自己的特殊间距,如下例所示:
# Set up constants for different time amounts:
SECONDS_PER_MINUTE = 60
SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE
SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR
SECONDS_PER_WEEK = 7 * SECONDS_PER_DAY
Black 将删除=赋值操作符前的多余空格,在我看来,这会使它们可读性更差:
# Set up constants for different time amounts:
SECONDS_PER_MINUTE = 60
SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE
SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR
SECONDS_PER_WEEK = 7 * SECONDS_PER_DAY
通过添加# fmt: off和# fmt: on注释,我们可以告诉 Black 关闭这些行的代码格式,然后恢复代码格式:
# Set up constants for different time amounts:
# fmt: off
SECONDS_PER_MINUTE = 60
SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE
SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR
SECONDS_PER_WEEK = 7 * SECONDS_PER_DAY
# fmt: on
在这个文件上运行 Black 现在不会影响这两个注释之间的代码格式。
总结
虽然好的格式是看不见的,但是糟糕的格式会使阅读代码变得令人心塞。风格是主观的,但是软件开发领域通常制定什么是好的和差的格式时,同时仍然为个人偏好留有余地。
Python 的语法使得它在风格方面相当灵活。如果你正在写别人永远看不到的代码,你可以想怎么写就怎么写。但是大部分软件开发是协作性的。无论您是与他人合作完成一个项目,还是仅仅想请更有经验的开发人员来评审您的工作,格式化您的代码以适应公认的风格指南都是非常重要的。
在编辑器中格式化你的代码是一项枯燥的任务,你可以用 Black 这样的工具来自动完成。本章介绍了 Black 为提高代码可读性而遵循的几条准则,包括垂直和水平方向的代码间距,以防止代码过于密集而不容易阅读,以及设置每行的长度限制。Black 为您执行这些规则,来降低您和其它合作者的沟通成本。
但是代码风格不仅仅是空格和决定单引号和双引号。例如,选择描述性变量名也是代码可读性的一个关键因素。虽然像 Black 这样的自动化工具可以做出语法决定,比如代码应该有多少间距,但是它们不能理解语义,比如什么是好的变量名。这是你的责任,我们将在下一章讨论这个话题。
译者注:随着 NLP 技术的飞速发着,出现了像 Copilot 等一系列优秀的工具,在让计算机理解语义这些方面都有很大的提升。这些工具是可以协助程序员想象出更适合的变量名的。
相关文章:
Python 进阶指南(编程轻松进阶):三、使用 Black 工具来格式化代码
原文:http://inventwithpython.com/beyond/chapter3.html 代码格式化是将一组规则应用于源代码,从而使得代码风格能够简洁统一。虽然代码格式对解析程序的计算机来说不重要,但代码格式对于可读性是至关重要的,这是维护代码所必需的…...
计算机应用辅导大纲及真题
00019考试 湖北省高等教育自学考试实践(技能)课程大纲 课程名称:计算机应用基础(实践) 课程代码:00019 实践能力的培养目标。 计算机应用基础(实践)是高等教育自学考试多…...
【Go基础】一篇文章带你全面了解学习—切片
目录 1、切片注意点 2、声明切片 3、切片初始化 4、切片的内存布局...
2022国赛28:centos8.5离线安装docker
大赛试题内容: 八、虚拟化(20分) 在Linux2上安装docker-ce,导入centos镜像。软件包和镜像存放在物理机D:\soft\DockerLinux。创建名称为skills的容器,映射Linux2的80端口到容器的80端口,在容器内安装apache2,默认网页内容为“HelloContainer”。解答过程: 下载CENTOS8镜…...
JVM专题
JVM类加载 Java里有如下几种类加载器: 引导类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如 rt.jar、charsets.jar等 扩展类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包应用程序…...
蓝桥杯模板题目
A:::::::::::::::小王子单链表(链表) 题目描述 小王子有一天迷上了排队的游戏,桌子上有标号为 1−10 的 10 个玩具,现在小王子将他们排成一列,可小王子还是太小了,他不确定他到底想把那个玩具摆在哪里&…...
SAP IDT - Building Data Foundation
To build a Data Foundation, it can be created on a Local Project view. Right-click under Local Project → New → Data Foundation. You can select a Single-source enabled or Multi-source enabled. Follow the wizard and select the connections. Data Foundatio…...
【Python】【进阶篇】三、Python爬虫的构建User-Agnet代理池
目录三、Python爬虫的构建User-Agnet代理池3.1 自定义UA代理池3.2 模块随机获取UA三、Python爬虫的构建User-Agnet代理池 在编写爬虫程序时,一般都会构建一个 User-Agent (用户代理)池,就是把多个浏览器的 UA 信息放进列表中&…...
数据结构.双链表的各种操作
//双链表 //单链表无法逆向检索,双链表可进可退 双链表比单链表多啦一个前驱指针 //双链表查找时间复杂度都为o(n) #include<bits/stdc.h> using namespace std; typedef struct donde //创建双链表 {int data;dnode *next,*prior; //前驱和后继 }dnode,*…...
去年12月被无情辞退,三个月后我携手自动化测试神技王者归来
引言 不知不觉在软件测试行业工作了3年之久,虽然说我是主做的功能测试,但是我也一直是兢兢业业的呀,不曾想去年7月份无情被辞的消息让我感到一阵沉重。我曾经一直坚信自己的技能和经验足以支撑我在这个领域的未来,但现实却告诉我&…...
区块链技术之共识机制
“共识机制”一词通常通俗地用于指代“股权证明”、“工作证明”或“权威证明”协议。然而,这些只是防止女巫攻击的共识机制的组成部分,共识机制是思想、协议和激励的完整堆栈,使一组分布式节点能够就区块链的状态达成一致。共识机制是区块链…...
SpringCloud断路器——Hystrix
Hystrix 本专栏学习内容来自尚硅谷周阳老师的视频 有兴趣的小伙伴可以点击视频地址观看 简介 Hystrix是一个用于处理分布式系统的延迟和容错的一个开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix…...
分布式 - 分布式体系架构:集群和分布式
文章目录01. 什么是集群?02. 集群为什么可以提高系统的可靠性?03. 集群为什么可以提高系统的性能?04. 什么是分布式计算?05. 如何进行分布式计算?06. 集群如何提高计算效率?07. 集群的优点和缺点࿱…...
NodeJs常用内置模块
目录 一、Path模块 二、fs模块 2.1、fs同步读取文件fs.readFileSync() 2.2、fs异步读取文件fs.readFile() 2.3、异步写入文件内容fs.writeFile() 三、Http模块 四、模块化 4.1、CommonJs的导入导出 4.2、ES6的导入导出 五、了解global和this 六、Sort()应用(数组排序…...
4.0 功能抢先看 | 读懂一个项目的研发效能 之 项目人效
思码逸企业版 4.0 的部分功能已进入内测阶段✨近期我们会用几篇文章,浅剧透一下 4.0 的新鲜功能。 最近几篇的主题将是 4.0 版本中的 GQM 看板——GQM 代表 Goal-Question-Metric(目标-问题-指标),是一套构建软件研发效能度量的系…...
Object方法
系列文章目录 前端系列文章——传送门 JavaScript系列文章——传送门 文章目录系列文章目录对象方法一、Object原型方法1、hasOwnProperty2、isPrototypeOf3、propertyIsEnumerable4、toString5、其他二、Object方法1、assign2、create3、defineProperties4、defineProperty5、…...
042:cesium加载Eris地图(多种形式)
第042个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中加载加载Eris地图。这里显示4种形式的地图,分别为:World_Imagery、World_Street_Map、World_Terrain_Base、World_Physical_Map。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示…...
第十四届蓝桥杯大赛软件赛省赛(C/C++B组)
目录试题 A. 日期统计1.题目描述2.解题思路3.模板代码试题 B.01 串的熵1.题目描述2.解题思路3.模板代码试题 C. 冶炼金属1.题目描述2. 解题思路3.模板代码试题 D. 飞机降落1.题目描述2. 解题思路3.模板代码试题 E. 接龙数列1.题目描述2. 解题思路3.模板代码试题 F. 岛屿个数1.题…...
Python生成随机验证码
pip install pillow 实现代码 import random from PIL import Image, ImageDraw, ImageFont,ImageFilterdef check_code(width120, height30, char_length5, font_filekumo.ttf, font_size28):code []img Image.new(modeRGB, size(width, height), color(255, 255, 255))draw…...
Longitudinal Change Detection on Chest X-rays Using Geometric Correlation Maps
文章来源:[MICCAI2019] Keywords:Chest X-ray;Longitudinal analysis;Change detection;Geometric correlation 一、本文提出的问题以及解决方案 在胸部X-ray图像的诊断中,医生会考虑与先前检查相比病变的…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
算法250609 高精度
加法 #include<stdio.h> #include<iostream> #include<string.h> #include<math.h> #include<algorithm> using namespace std; char input1[205]; char input2[205]; int main(){while(scanf("%s%s",input1,input2)!EOF){int a[205]…...
