为什么我使用%尝试替换像{0}这样的占位符时会出现“TypeError:not all arguments converted during string formatting”错误?

287

我有一些代码,可以从用户那里读取两个字符串:

name1 = input("Enter name 1: ")
name2 = input("Enter name 2: ")

以后,我想将这些字符串格式化成一个更长的字符串以供打印:
if len(name1) > len(name2):
    print ("'{0}' is longer than '{1}'"% name1, name2)

但是我得到了一个看起来像这样的错误信息:
Traceback (most recent call last):
  File "program.py", line 13, in <module>
    print ("'{0}' is longer than '{1}'"% name1, name2)
TypeError: not all arguments converted during string formatting

代码有什么问题?我应该如何编写这一行,以便正确格式化字符串?


有关此类字符串格式化的最常用方法的深入比较,请参见String formatting: % vs. .format vs. f-string literal,有关此类字符串构建的一般操作指南,请参见How do I put a variable’s value inside a string (interpolate it into the string)?。请参见Printing tuple with string formatting in Python,其中介绍了另一个常见的错误原因。

9个回答

290

旧式的%格式化使用%代码进行格式化:

# A single value can be written as is:
'It will cost $%d dollars.' % 95

# Multiple values must be provided as a tuple:
"'%s' is longer than '%s'" % (name1, name2)

新式的{}格式化使用{}代码和.format方法。请确保不要混用-如果“模板”字符串包含{}占位符,则调用.format,而不是使用%
# The values to format are now arguments for a method call,
# so the syntax is the same either way:
'It will cost ${0} dollars.'.format(95)

"'{0}' is longer than '{1}'".format(name1, name2)

37
在Python 3.6中,f"'It will cost ${your_variable} dollars."的意思是:在字符串前缀加上字母"f",然后使用花括号和变量名来插入变量值,最终得到一个包含变量值的字符串。例如,如果变量your_variable的值为100,那么这个代码将会输出字符串:"It will cost 100 dollars." - JinSnow
3
补充 @JinSnow 的评论...如果你希望打印变量名称,可以使用f"'It will cost {your_variable=} dollars." - Sam Daniel

63

13
迄今为止(Python 3.5),"将来可能会被弃用"的声明尚未实现。旧的'%'语法在3.1并未被弃用,只有在3.2版本中logging模块学会了如何使用新格式样式‘{}’进行格式化。突然间,在3.5版本中出现了PEP 461:对于字节,'% '格式的支持。这使我认为'%'符号仍将继续存在很长一段时间。 - cfi
10
% 更加简洁,很高兴它跟我们在一起。 - Lenar Hoyt
3
我同意。百分号更加简洁,去掉它对语言没有任何益处。 - chevydog
@LenarHoyt 你对f-strings有什么看法?我无法想象"'%s' is longer than '%s'" % (name1, name2)f"'{name1}' is longer than '{name2}'"更简洁。 - Mark Moretto
f-strings通常更简洁,但在某些情况下,仍然可以使用%,例如当您想要对参数进行多行计算或包含其他字符串的计算时。 - Lenar Hoyt
显示剩余2条评论

55

我宁愿使用以下语句将元组转换为字符串:print("this is a tuple: %s" % str(thetuple))print("this is a tuple: %s" % repr(thetuple)) - Alex

6

除了其他两个答案之外,我认为最后两个条件的缩进也是不正确的。 这些条件是一个名字比另一个名字长,并且它们需要以“elif”开头并且没有缩进。如果您将其放在第一个条件内(通过从边缘给出四个缩进),则会产生矛盾,因为名称的长度不能同时相等和不同。

    else:
        print ("The names are different, but are the same length")
elif len(name1) > len(name2):
    print ("{0} is longer than {1}".format(name1, name2))

6

请记住,这个错误也可能是由于忘记引用变量导致的。

"this is a comment" % comment #ERROR

代替

"this is a comment: %s" % comment

5

在Python 3.7及以上版本中,有一种新且简单的方法,称为f字符串。以下是语法:

name = "Eric"
age = 74
f"Hello, {name}. You are {age}."

输出:

Hello, Eric. You are 74.

2
这实际上并没有回答问题。 - pppery

0

对我来说,由于我在单个打印调用中存储了许多值,解决方案是创建一个单独的变量将数据存储为元组,然后调用打印函数。

x = (f"{id}", f"{name}", f"{age}")
print(x) 

0

将字符串数字强制转换为整数最简单的方法

number=89
number=int(89)

这指的是一个无关的问题。请参见例如 https://dev59.com/nonis4cB2Jgan1znDcZj。 - Karl Knechtel

-1

我也遇到了这个错误,

_mysql_exceptions.ProgrammingError: not all arguments converted during string formatting 

但是列表参数运行良好。

我使用mysqlclient python库。该库似乎不接受元组参数。传递像['arg1','arg2']这样的列表参数将起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接