结合f-string和原始字符串字面值

120

我想知道如何在使用r获取原始字符串文字的同时使用f-string。 我目前的代码如下,但希望允许任何名称替换Alex。 我正在考虑添加一个f-string,然后用花括号替换Alex并将用户名放入其中,但这与r不兼容。

username = input('Enter name')
download_folder = r'C:\Users\Alex\Downloads'

2
你可以使用 print("{0}".format(variable)) - Alex_P
完美,谢谢! - lammyalex
1
"...但这在r中不起作用。为什么?你遇到了哪个错误?你正在尝试什么代码?" - Georgy
6个回答

231
你可以将f字符串的f与原始字符串的r结合起来使用:
user = 'Alex'
dirToSee = fr'C:\Users\{user}\Downloads'
print (dirToSee) # prints C:\Users\Alex\Downloads

r 只禁用反斜杠转义序列处理,而不禁用 f-string 处理。

引用文档

‘f’ 可以与 ‘r’ 结合使用,但不能与 ‘b’ 或 ‘u’ 结合使用,因此可以使用原始格式化字符串,但不能使用格式化字节文字。

...

除非存在 ‘r’ 或 ‘R’ 前缀,否则会解释字符串和字节文字中的转义序列...


3
啊,太好了,谢谢你。我尝试用rf做这件事但没有成功。 - lammyalex
7
"rf" 也可以使用。请参考字符串和字节字符串 - Georgy
3
在使用 fr 时,PyCharm IDE 显示错误,但当运行代码时,它可以正常工作,没有任何问题。 - VBJ
4
对我来说,这是一个警告而不是错误:它与早期版本的Python不兼容。它可以在Python 3.6及更高版本上正常运行。 - rajah9
2
f-strings 在 3.5 及以下版本已经不被支持,因此使用 rffr 作为前缀并不会引起特殊的兼容性问题。 - Karl Knechtel
显示剩余4条评论

18

另外,您还可以使用str.format()方法。

name = input("What is your name? ")
print(r"C:\Users\{name}\Downloads".format(name=name))

这将通过插入name标签的值来格式化原始字符串。


我认为这是一个很好的替代方案!感谢您添加这个。 - Ice Bear

4

正如其他人提到的那样,混合使用 rf 是可以做到的。 不过要小心,因为插值字符串默认情况下不是原始的:

not_escaped = "\not_escaped"
half_escaped = rf"escaped_{not_escaped}"

print(half_escaped)
### outputs:
# escaped_
# ot_escaped

对于插值字符串,您也需要使用 r

escaped = r"\n_escaped"
full_escaped = rf"escaped_too_{escaped}"

print(full_escaped)
# escaped_too_\n_escaped

3

由于您正在处理文件路径,我建议避免使用f-strings,而是使用专门用于路径操作的库。例如,pathlib 可以让您执行以下操作:

from pathlib import Path
username = input('Enter name')
download_folder = Path('C:/Users', username, 'Downloads')

这种方法还提供了其他常见的文件操作,例如is_diropen。或者,您也可以使用os.path.join

很好知道,我从未注意到可以为“Path(...)”指定多个参数。 - Eric Duminil
1
是的,它也等同于 Path('C:/Users') / username / 'Downloads' - Nameless One

2
我发现最简单的方法是使用隐式换行来将字符串拆分为组件部分,即在括号内分离'r'和'f'字符串。这里有一个matplotlib标题的示例,包含“普通”、“格式化”和“原始”字符串字面量(在此处阅读更多信息):
plt.title('Blind Surveys 01-FEB-2022\n'
         f'Recording{n}; Mean dose rate: {m.get_mean_doserate()*1000:.4f}'
         r' $\mathrm{\mu}$Sv/hr', fontsize='x-large')

enter image description here

为了更好地回答问题,您还可以在变量声明中使用隐式行连续符:

user = ‘Alex’
dir_out = (r‘C:\Users\’
           f‘{user}’
           r‘\Downloads’)
print(dir_out) #C:\Users\Alex\Downloads

可以承认,对于这种简单的情况来说可能有点过度,但当字符串变得更加复杂时,它将成为你的好帮手!


1
有趣。最后一个例子看起来很好,易读。另一种选择是使用pathlib并让它使用“/”连接路径。 - Eric Duminil

-2
你可以试试:
username = input('Enter name')
download_folder = r'C:\Users\Alex\Downloads'
download_folder = download_folder.replace("Alex", username)
print(download_folder)

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