我想把一个整型放入字符串中。这就是我现在正在做的事情:

num = 40
plot.savefig('hanning40.pdf') #problem line

我必须为几个不同的数字运行程序,所以我想做一个循环。但是像这样插入变量是行不通的:

plot.savefig('hanning', num, '.pdf')

如何将变量插入到Python字符串中?


另请参阅

如果您尝试使用+来连接一个数字与字符串(或字符串之间等)并得到错误消息,请参阅如何连接str和int对象。

如果您试图用可变数据组合一个URL,不要使用普通的字符串格式,因为这很容易出错,而且比必要的难度更大。有专门的工具可用。参见在Python中向给定URL添加参数。

如果您试图组合一个SQL查询,不要使用普通字符串格式,因为这是一个主要的安全风险。这就是“SQL注入”的原因,它每年花费真实的公司大量的钱。例如,请参阅Python:连接MySQL和执行查询的最佳实践和最安全的方法,以获得适当的技术。

如果你只是想打印(输出)字符串,你可以先这样准备它,或者如果你不需要字符串做其他的事情,使用一个单独的调用打印输出的每一部分。参见如何在同一行上打印多个东西(固定文本和/或变量值),一次全部?有关这两种方法的详细信息。


plot.savefig('hanning(%d).pdf' % num)

当跟在字符串后面时,%操作符允许您通过格式代码(在本例中为%d)向该字符串中插入值。要了解更多细节,请参阅Python文档:

printf-style字符串格式


你可以像使用str()一样使用+作为普通的字符串连接函数。

"hello " + str(10) + " world" == "hello 10 world"

一般来说,你可以使用以下方法创建字符串:

stringExample = "someString " + str(someNumber)
print(stringExample)
plot.savefig(stringExample)

使用f-strings:

plot.savefig(f'hanning{num}.pdf')

这是在3.6中添加的,是新的首选方式。


使用str.format ():

plot.savefig('hanning{0}.pdf'.format(num))

字符串连接:

plot.savefig('hanning' + str(num) + '.pdf')

转换说明符:

plot.savefig('hanning%s.pdf' % num)

使用局部变量名(巧妙的技巧):

plot.savefig('hanning%(num)s.pdf' % locals())

使用字符串。模板:

plot.savefig(string.Template('hanning${num}.pdf').substitute(locals()))

参见:

更花哨的输出格式- Python教程 Python 3的f-Strings:改进的字符串格式化语法(指南)- RealPython


我需要一个扩展版本:我不需要在字符串中嵌入单个数字,而是需要生成'file1.pdf'、'file2.pdf'等形式的一系列文件名。它是这样运作的:

['file' + str(i) + '.pdf' for i in range(1,4)]

随着Python 3.6中引入了格式化字符串字面量(简称“f-strings”),现在可以用更简洁的语法来编写:

>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'

在问题中给出的例子中,它看起来是这样的

plot.savefig(f'hanning{num}.pdf')

如果你想在字符串中放入多个值,你可以使用format

nums = [1,2,3]
plot.savefig('hanning{0}{1}{2}.pdf'.format(*nums))

将生成字符串hanning123.pdf。这可以用任何数组来实现。


你可以在你的字符串中使用字典和替换变量。

var = {"name": "Abdul Jalil", "age": 22}
temp_string = "My name is %(name)s. I am %(age)s years old." % var

特殊情况

根据变量数据与字符串一起使用的原因,通用方法可能不合适。

如果您需要准备一个SQL查询

不要使用任何常用的技术来组装字符串。相反,使用SQL库的功能进行参数化查询。

A query is code, so it should not be thought about like normal text. Using the library will make sure that any inserted text is properly escaped. If any part of the query could possibly come from outside the program in any way, that is an opportunity for a malevolent user to perform SQL injection. This is widely considered one of the important computer security problems, costing real companies huge amounts of money every year and causing problems for countless customers. Even if you think you know the data is "safe", there is no real upside to using any other approach.

语法将取决于您正在使用的库,并且超出了这个答案的范围。

如果您需要准备一个URL查询字符串

参见在Python中向给定URL添加参数。不要自己动手;没有任何实际的理由让你的生活更加艰难。

写入文件

虽然可以提前准备一个字符串,但使用单独的.write调用来写入每条数据可能更简单,也更节省内存。当然,在编写之前,非字符串仍然需要转换为字符串,这可能会使代码复杂化。这里没有一个放之四海而皆准的答案,但选择不当通常不会有太大影响。

如果你只是调用打印

内置的print函数接受可变数量的参数,并且可以接受任何对象并使用str对其进行字符串化。在尝试字符串格式化之前,请考虑简单地传递多个参数是否可以达到您的目的。(你也可以使用sep关键字参数来控制参数之间的间距。)

# display a filename, as an example
print('hanning', num, '.pdf', sep='')

当然,对于程序来说,组装字符串是有用的,可能还有其他原因;所以在适当的时候一定要这样做。

需要注意的是,打印是一个特殊情况。唯一以这种方式工作的函数是显式编写为以这种方式工作的函数。对于普通的函数和方法,比如input,或者Matplotlib图的savefig方法,我们需要自己准备一个字符串。

连接

Python支持在两个字符串之间使用+,但不支持在字符串和其他类型之间使用+。为了解决这个问题,我们需要显式地将其他值转换为字符串:'hanning' + str(num) + '.pdf'。

基于模板的方法

解决这个问题的大多数方法都包括使用某种“模板”字符串,其中包含“占位符”,显示应该在哪里添加信息,然后使用一些函数或方法添加缺少的信息。

f-strings

这是在可能的情况下推荐使用的方法。它看起来像f'hanning{num}.pdf'。要插入的变量名直接出现在字符串中。值得注意的是,实际上并没有“f弦”这样的东西;它不是一个单独的类型。相反,Python会提前翻译代码:

>>> def example(num):
...     return f'hanning{num}.pdf'
... 
>>> import dis
>>> dis.dis(example)
  2           0 LOAD_CONST               1 ('hanning')
              2 LOAD_FAST                0 (num)
              4 FORMAT_VALUE             0
              6 LOAD_CONST               2 ('.pdf')
              8 BUILD_STRING             3
             10 RETURN_VALUE

因为它是一种特殊的语法,所以它可以访问在其他方法中不使用的操作码。

str.format

当f-string不可能时,这是推荐的方法——主要是因为模板字符串需要提前准备,然后再填充。它看起来像'hanning{}.pdf'.format(num),或'hanning{num}.pdf'.format(num=num)'。这里,format是一个内置于字符串中的方法,它可以通过位置或关键字接受参数。

特别是对于str.format,知道内置的locals、globals和vars函数返回将变量名映射到这些变量内容的字典是很有用的。因此,而不是像'{a}{b}{c}'。Format (a=a, b=b, c=c),我们可以使用'{a}{b}{c}'. Format (**locals()),解包locals()字典。

str.format_map

这是.format的一个罕见变体。它看起来像'hanning{num}.pdf'。format_map({“num”:num})。它不接受关键字参数,而是接受一个映射参数。

That probably doesn't sound very useful - after all, rather than 'hanning{num}.pdf'.format_map(my_dict), we could just as easily write 'hanning{num}.pdf'.format(**my_dict). However, this is useful for mappings that determine values on the fly, rather than ordinary dicts. In these cases, unpacking with ** might not work, because the set of keys might not be determined ahead of time; and trying to unpack keys based on the template is unwieldy (imagine: 'hanning{num}.pdf'.format(num=my_mapping[num]), with a separate argument for each placeholder).

字符串。格式化程序

string标准库模块包含一个很少使用的Formatter类。使用它看起来像string.Formatter().format('hanning{num}.pdf', num=num)。模板字符串再次使用相同的语法。这显然比在字符串上调用.format要笨拙;其动机是允许用户子类化Formatter,为模板字符串定义不同的语法。

以上所有方法都使用一种通用的“格式化语言”(尽管字符串。Formatter允许更改它);还有许多其他东西可以放在{}中。解释它是如何工作的超出了这个答案的范围;请查阅文档。请记住,字面{和}字符需要通过将它们加倍来转义。语法可能是受c#的启发。

%操作符

这是一种解决问题的传统方法,受到C和c++的启发。很长一段时间以来,它一直不被鼓励,但仍然受到支持。对于简单的情况,它看起来像'hanning%s.pdf' % num。正如您所期望的那样,模板中的文字“%”符号需要加倍来转义。

它有一些问题:

It seems like the conversion specifier (the letter after the %) should match the type of whatever is being interpolated, but that's not actually the case. Instead, the value is converted to the specified type, and then to string from there. This isn't normally necessary; converting directly to string works most of the time, and converting to other types first doesn't help most of the rest of the time. So 's' is almost always used (unless you want the repr of the value, using 'r'). Despite that, the conversion specifier is a mandatory part of the syntax. Tuples are handled specially: passing a tuple on the right-hand side is the way to provide multiple arguments. This is an ugly special case that's necessary because we aren't using function-call syntax. As a result, if you actually want to format a tuple into a single placeholder, it must be wrapped in a 1-tuple. Other sequence types are not handled specially, and the different behaviour can be a gotcha.

字符串。模板

string标准库模块包含一个很少使用的Template类。实例提供了substitute和safe_substitute方法,它们的工作原理类似于内置的.format (safe_substitute将保留占位符,而不是在参数不匹配时引发异常)。这也应该被认为是解决问题的一种遗留方法。

它看起来像string.Template('hanning$num.pdf').substitute(num=num),受到传统Perl语法的启发。它显然比.format方法更笨拙,因为在方法可用之前必须使用一个单独的类。大括号({})可以在变量名周围使用,以避免歧义。与其他方法类似,模板中的文字'$'需要加倍进行转义。