python 如何将变量的值放入字符串中(将其插入字符串中)?

ttisahbt  于 2023-04-04  发布在  Python
关注(0)|答案(9)|浏览(291)

我想把一个int放进一个string中。这是我现在正在做的:

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

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

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

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

另请参见

如果您尝试使用+将数字与字符串(或字符串之间的字符串等)连接起来并得到错误消息,请参阅How can I concatenate str and int objects?
如果你试图创建一个文件路径,请参阅How can I create a full path to a file from parts (e.g. path to the folder, name and extension)?以获取其他技术。通常使用特定于创建路径的代码会更好。
如果你试图用可变数据组装一个URL,* 不要 * 使用普通的字符串格式,因为它容易出错,而且比必要的更困难。可以使用专门的工具。参见Add params to given URL in Python
如果您尝试组装SQL查询,请不要使用普通的字符串格式,因为这是主要的安全风险。这是导致costs real companies huge amounts of money every year“SQL注入”的原因。正确的技巧请参见示例How to use variables in SQL statement in Python?
如果你只想print(输出)字符串,你可以先这样准备,如果你不需要字符串做其他任何事情,使用一个对print的调用单独打印输出的每一段。有关这两种方法的详细信息,请参阅How can I print multiple things (fixed text and/or variable values) on the same line, all at once?

1sbrub3j

1sbrub3j1#

使用f字符串:

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())

使用string.Template

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

参见:

czq61nw1

czq61nw12#

在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')
wlsrxk51

wlsrxk513#

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

%操作符,当跟随一个字符串时,允许你通过格式代码(在本例中是%d)将值插入到该字符串中。有关更多详细信息,请参阅Python文档:
printf-style字符串格式

jei2mxaa

jei2mxaa4#

您可以使用+作为普通的字符串连接函数,也可以使用str()

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

j7dteeu85#

通常,可以使用以下命令创建字符串:

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

khbbv19g6#

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

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

将得到字符串hanning123.pdf。这可以用任何数组来完成。

wsxa1bj1

wsxa1bj17#

特殊情况

根据为什么变量数据与字符串一起使用,通用方法可能不合适。

如果需要准备SQL查询

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

一个查询是代码,所以它不应该被认为是普通的文本。使用库将确保任何插入的文本都被正确地转义。如果查询的任何部分可能以任何方式来自程序外部,那就是恶意用户执行SQL injection的机会。这被广泛认为是重要的计算机安全问题之一。每年给真实的的公司造成巨额的成本,并给无数的客户带来问题。即使你认为你知道数据是“安全的”,使用任何其他方法都没有真正的好处。
语法将取决于您正在使用的库,并且超出了本答案的范围。

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

参见Add params to given URL in Python。不要自己做;没有任何实际的理由让你的生活更艰难。

写入文件

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

如果只是调用print

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

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

当然,可能还有其他的原因,为什么程序汇编一个字符串是有用的;所以在适当的情况下尽一切可能这样做。
需要注意的是,print是一个特例。只有那些被显式编写为以这种方式工作的函数才能以这种方式工作。对于普通的函数和方法,比如input,或者Matplotlib plots的savefig方法,我们需要自己准备一个字符串。

拼接

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

模板化方式

解决这个问题的大多数方法都涉及到某种“模板”字符串,其中包括显示应添加信息的位置的“占位符”,然后使用某种函数或方法来添加缺少的信息。

f字符串

如果可能的话,这是推荐的方法。它看起来像f'hanning{num}.pdf'。要插入的变量的名称直接出现在字符串中。重要的是要注意 * 实际上没有“f-string”* 这样的东西;它不是一个单独的类型。相反,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

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

一米十一分

这是当f字符串不可能时推荐的方法-主要是因为模板字符串需要提前准备并稍后填充。它看起来像'hanning{}.pdf'.format(num)'hanning{num}.pdf'.format(num=num)'。在这里,format是一个内置于字符串的方法,它可以通过位置或关键字接受参数。
特别是对于str.format,了解内置的localsglobalsvars函数返回的字典将变量名Map到这些变量的内容是很有用的。因此,我们可以使用'{a}{b}{c}'.format(**locals())unpackinglocals() dict,而不是像'{a}{b}{c}'.format(a=a, b=b, c=c)这样的东西。

str.format_map

这是.format的一个罕见变体。它看起来像'hanning{num}.pdf'.format_map({'num': num})。它不接受关键字参数,而是接受一个Map的单个参数。
这听起来可能不是很有用-毕竟,与'hanning{num}.pdf'.format_map(my_dict)相比,我们可以很容易地写'hanning{num}.pdf'.format(**my_dict)。然而,这对于动态确定值的Map很有用,而不是普通的dict s。在这些情况下,使用**解包可能不起作用,因为键集可能无法提前确定;并且尝试基于模板解包密钥是笨拙的(想象一下:'hanning{num}.pdf'.format(num=my_mapping[num]),每个占位符都有一个单独的参数)。

string.Formatter

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

上述所有方法都使用一种通用的“格式化语言”(尽管string.Formatter允许更改它);{}里面还有很多其他的东西。解释它是如何工作的超出了这个答案的范围;请参考文档。2请记住,文字{}字符需要通过加倍来转义。3语法可能是受C#启发的。

%运算符

这是一种解决这个问题的传统方法,受C和C++的启发。它已经被劝阻了很长一段时间,但仍然受到支持。它看起来像'hanning%s.pdf' % num,用于简单的情况。正如你所期望的那样,模板中的文字'%'符号需要加倍才能转义它们。
它有一些问题:

  • 看起来转换说明符(%后面的字母)应该匹配任何被插值的类型,但事实并非如此。相反,值被转换为指定的类型,然后从那里 * 转换为字符串 *。这通常是不必要的;大多数情况下,直接转换为字符串是有效的,而在其他情况下,先转换为其他类型并没有什么帮助。因此,几乎总是使用's'(除非您想要值的repr,使用'r')。尽管如此,转换说明符是语法的强制部分。
  • 元组被特殊处理:在右边传递一个元组是提供多个参数的方法。这是一个丑陋的特殊情况,因为我们没有使用函数调用语法。因此,如果你真的想把一个元组格式化为一个占位符,它必须被 Package 在一个1元组中。
  • 其他的序列类型没有被特殊处理,不同的行为可能是一个陷阱。

string.Template

string标准库模块包含一个很少使用的Template类。示例提供了substitutesafe_substitute方法,其工作方式与内置的.format类似(safe_substitute将保留占位符不变,而不是在参数不匹配时引发异常)。这也应该被视为解决该问题的传统方法。
它看起来像string.Template('hanning$num.pdf').substitute(num=num),受传统Perl语法的启发。它显然比.format方法更笨拙,因为在方法可用之前必须使用一个单独的类。({})可以可选地用于变量名称周围,以避免歧义。与其他方法类似,模板中的文字'$'需要加倍以进行转义。

jvidinwx

jvidinwx8#

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

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

yqyhoc1h9#

你可以在你的字符串中创建dict和替换变量。

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

相关问题