Skip to content

Chapter2 Str

Python 中有多种数据类型。您可能最常看到的主要数据类型是字符串、整数、浮点数、列表、字典和元组。在本章中,我们将介绍字符串数据类型。您会惊讶地发现,可以立即使用 Python 中的字符串做很多事情。还有一个内建的string模块,您可以导入它以访问更多功能,但我们不会在本章中讨论它。

我们将涵盖以下主题:

  • 字符串创建
  • 字符串拼接
  • 字符串方法
  • 字符串切片
  • 字符串替换

创建字符串

字符串通常可以通过三种方式创建,我们可以使用单引号、双引号或三引号。

my_string = "Welcome to Python!"
another_string = 'The bright red fox jumped the fence.'
a_long_string = '''This is a
multi-line string. It covers more than
one line'''

三引号行可以用三个单引号或三个双引号来完成。无论哪种方式,它们都允许程序员在多行上编写字符串。如果将其打印出来,您会注意到输出保留了换行符。如果您需要在字符串中使用单引号,请将其用双引号引起来。请参见以下示例。

my_string = "I'm a Python programmer!"
otherString = 'The word "python" usually refers to a snake'
tripleString = """Here's another way to embed "quotes" in a string"""

实际上还有另一种创建字符串的方法,那就是使用 str 方法。它是这样工作的:

s = int("123")

需要注意的是,字符串是 Python 不可变类型之一。这意味着您不能在创建后更改字符串的内容。

让我们试着改变一个看看会发生什么:

my_string = "abc"
my_string[0] = "d"
输出:
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
TypeError: 'str' object does not support item assignment
在这里,我们尝试将第一个字符从“a”更改为“d”;然而,这会引发一个 TypeError,阻止我们这样做。

现在您可能会认为,通过将新字符串分配给您已更改字符串的同一个变量。让我们看看这是不是真的:

>>> my_string = "abc"
>>> id(my_string)
19397208
>>> my_string = "def"
>>> id(my_string)
25558288
>>> my_string = my_string + "ghi"
>>> id(my_string)
31345312
通过检查对象的 id,我们可以确定每当我们为变量分配一个新值时,它的身份都会发生变化。

字符串拼接

连接意思是将两个事物组合或相加。在这种情况下,我们想知道如何将两个字符串相加。此操作在 Python 中非常简单:

>>> string_one = "My dog ate "
>>> string_two = "my homework!"
>>> string_three = string_one + string_two
“+”运算符将两个字符串连接成一个。

字符串方法

字符串是 Python 中的一个对象。事实上,Python 中的一切都是对象,目前只需知道字符串有自己的内置方法就足够了。

例如,假设您有以下字符串:

my_string = "This is a string!"

现在你想让这个字符串完全大写。为此,您需要做的就是调用它的 upper() 方法,如下所示:

>>> my_string.upper()

如果你打开了解释器,你也可以像这样做同样的事情:

"This is a string!".upper()

还有许多其他字符串方法。例如,如果您希望所有内容都是小写的,您可以使用 lower() 方法;如果你想删除所有的前导和尾随空白,你可以使用 strip()

要获得所有字符串方法的列表,请在解释器中键入以下命令:

>>> dir(my_string)

您将看到如下内容:

['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

您可以忽略以双下划线开头和结尾的特殊方法,例如 __add__。它们不会在每天的 Python 编码中使用。而是专注于其他。如果你想知道其中一个是做什么的,请寻求帮助。例如,假设您想了解 capitalize 的用途。要找出答案,您可以输入:

>>> help("HelloWorld".capitalize)
这将返回以下信息:
Help on built-in function capitalize:
capitalize() method of builtins.str instance
    Return a capitalized version of the string.

    More specifically, make the first character have upper case and the rest lower
    case.

你刚刚对一个叫做内省机制的话题有了一点了解。 Python 允许对其所有对象进行简单的内省,这使得它非常易于使用。基本上,内省允许你询问 Python 自身。在前面的部分中,您了解了类型转换。您可能想知道如何判断变量的类型(即 int 或 string)。你可以让 Python 告诉你!

>>> type(my_string)
输出:
<type 'str'>
可以看到,my_string 变量的类型是 str!

字符串切片

您会发现自己在现实世界中经常做的一个主题是字符串切片。让我们看一下切片如何使用以下字符串:

>>> my_string = "I like Python!"

可以使用切片访问字符串中的每个字符。例如,如果我只想抓取第一个字符,我可以这样做:

>>> my_string[0:1]
这提取到了字符串中的第一个字符,但不包括第二个字符。是的,Python的索引下标是从零开始的。

如果我们将每个字符在表格中的位置映射出来,就更容易理解了:

0 1 2 3 4 5
P y t h o n

因此我们有一个 6 个字符长的字符串,从 0 开始到 5。

让我们再举几个例子,让这些概念更好地进入我们的脑海。

>>> my_string[:1]
'I'
>>> my_string[0:12]
'I like Pytho'
>>> my_string[0:13]
'I like Python'
>>> my_string[0:14]
'I like Python!'
>>> my_string[0:-5]
'I like Py'
>>> my_string[:]
'I like Python!'
>>> my_string[2:]
'like Python!'

从这些示例中可以看出,我们可以通过指定切片的开头(即 my_string[2:])、切片的结尾(即 my_string[:1])或两者(即 my_string[0 :13])。我们甚至可以使用从字符串末尾开始的负值。所以我们做 my_string[0:-5] 的例子从零开始,但在字符串结束前 5 个字符结束。

您可能想知道在什么地方使用它。我发现自己使用它来解析文件中固定宽度的记录,或者偶尔用于解析遵循非常特定命名约定的复杂文件名。我还用它来解析二进制类型文件中的值。如果您了解切片以及如何有效地使用它,那么任何需要进行文本文件处理的工作都会变得更加容易。

您还可以通过索引访问字符串中的单个字符。这是一个例子:

>>> print(my_string[0])
上面的代码将打印出字符串中的第一个字符。

字符串格式化

字符串格式化(AKA 替换)是将值替换为基本字符串的主题。大多数时候,您将在字符串中插入字符串;然而,您也会发现自己也经常将整数和浮点数插入到字符串中。

有两种不同的方法可以完成此任务。我们将从传统方式开始,然后转向新的。

  • Ye Olde 替换字符串的方法

了解如何执行此操作的最简单方法是查看一些示例。

>>> my_string = "I like %s" % "Python"
>>> my_string
'I like Python'
>>> var = "cookies"
>>> newString = "I like %s" % var
>>> newString
'I like cookies'
>>> another_string = "I like %s and %s" % ("Python", var)
>>> another_string
'I like Python and cookies'

正如你看到的那样,%s 是上面代码中的重要部分。它告诉 Python 您可能很快就会插入文本。如果您在字符串后跟一个百分号和另一个字符串或变量,那么 Python 将尝试将它插入到字符串中。您可以通过在字符串中放置多个 %s 实例来插入多个字符串。你会在最后一个例子中看到这一点。请注意,当您插入多个字符串时,您必须用括号将要插入的字符串括起来。

现在让我们看看如果我们没有插入足够的字符串会发生什么:

>>> another_string = "I like %s and %s" % "Python"
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
TypeError: not enough arguments for format string
哦嚯!我们没有传递足够的参数来格式化字符串!如果仔细查看上面的示例,您会注意到它有两个 %s 实例,因此要向其中插入字符串,您必须向它传递相同数量的字符串!

现在我们准备学习插入整数和浮点数。让我们来看看!

>>> my_string = "%i + %i = %i" % (1,2,3)
>>> my_string
'1 + 2 = 3'
>>> float_string = "%f" % (1.23)
>>> float_string
'1.230000'
>>> float_string2 = "%.2f" % (1.23)
>>> float_string2
'1.23'
>>> float_string3 = "%.2f" % (1.237)
>>> float_string3
'1.24'

上面的第一个例子,很明显,我们创建了一个接受三个参数的字符串并将它们传入。以防万一你还没有弄明白,不,Python 在第一个例子中实际上并没有做任何加法。 对于第二个例子,我们传入一个浮点数。请注意,输出包含许多额外的零。我们不希望这样,所以我们告诉 Python 在第三个示例(“%.2f”)中将其限制为小数点后两位。 最后一个例子告诉你,如果你传递一个大于两位小数的浮点数,Python 会为你做一些舍入。

现在让我们看看如果我们传递错误数据会发生什么:

>>> int_float_err = "%i + %f" % ("1", "2.00")
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
TypeError: %d format: a number is required, not str
在这个例子中,我们传递给它两个字符串而不是一个整数和一个浮点数。这会引发 TypeError 并告诉我们 Python 需要一个数字。 这指的是不传递整数,所以让我们解决这个问题,看看是否能解决问题:
>>> int_float_err = "%i + %f" % (1, "2.00")
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
TypeError: float argument required, not str

并没有。我们得到了同样的错误,但是一条不同的消息告诉我们应该传递一个浮点数。如您所见,Python 为我们提供了有关错误原因和修复方法的非常好的信息。如果您适当地修复了输入,那么您应该能够运行此示例。

  • 模板和新的字符串格式化方法

这个新方法实际上是在 Python 2.4 中作为字符串模板添加回来的,但在 Python 2.6 中是通过格式化方法作为常规字符串方法添加的。所以这并不是真正的新方法,只是更新了。不管怎样,让我们从模板开始吧!

>>> print("%(lang)s is fun!" % {"lang":"Python"})
Python is fun!

这可能看起来很奇怪,但基本上我们只是将 %s 更改为 %(lang)s,这基本上是 %s 里面有一个变量。第二部分实际上称为我们将在下一节中学习的 Python 字典。基本上它是一个键值对,所以当 Python 在字符串和传入的字典的键中看到键“lang”时,它会用它的值替换该键。

让我们再看一些示例:

>>> print("%(value)s %(value)s %(value)s !" % {"value":"SPAM"})
SPAM SPAM SPAM !
>>> print("%(x)i + %(y)i = %(z)i" % {"x":1, "y":2})
Traceback (most recent call last):
  File "<string>", line 1, in <fragment>
KeyError: 'z'
>>> print("%(x)i + %(y)i = %(z)i" % {"x":1, "y":2, "z":3})
1 + 2 = 3

在第一个示例中,您会注意到我们只传入了一个值,但它被插入了 3 次!这是使用模板的优点之一。第二个例子有一个问题,我们忘记传递一个键,即“z”键。第三个示例纠正了这个问题并显示了结果。现在让我们看看如何用字符串的格式化方法做一些类似的事情!

>>> "Python is as simple as {0}, {1}, {2}".format("a", "b", "c")
'Python is as simple as a, b, c'
>>> "Python is as simple as {1}, {0}, {2}".format("a", "b", "c")
'Python is as simple as b, a, c'
>>> xy = {"x":0, "y":10}
>>> print("Graph a point at where x={x} and y={y}".format(**xy))
Graph a point at where x=0 and y=10

在前两个示例中,您可以看到我们如何按位置传递项目。如果我们重新排列顺序,我们会得到稍微不同的输出。最后一个例子使用了一个字典,就像我们在上面的模板中使用的一样。但是,我们必须使用双星号提取字典才能使其在此处正常工作。

您还可以对字符串执行许多其他操作,例如指定宽度、对齐文本、转换为不同的基数等等。

请务必查看下面的一些参考资料以获取更多信息。 - Python’s official documentation on the str type - String Formatting - More on String Formatting

我们在本章中介绍了很多内容。我们来回顾一下:

首先,我们学习了如何自己创建字符串。然后我们继续讨论字符串连接的主题。之后,我们查看了字符串对象提供给我们的一些方法。接下来我们研究了字符串切片,最后学习了字符串替换。

在下一章中,我们将研究另外三种 Python 的内置数据类型:列表、元组和字典。