当前位置: 首页 > 后端技术 > Python

为什么Python的f-string可以拼接字符串和数字?

时间:2023-03-26 01:28:09 Python

本文出自《WhyPython》系列,存档在Github:https://github.com/chinesehuazhou/python-whydo毫无疑问,Python是一门强类型语言。强类型语言。强类型语言!(关于强弱类型的话题,推荐阅读这篇技术科普文章)这意味着不同类型的对象通常需要显式转换才能进行某些操作。下面以字符串和数字为例,看看强制操作的结果会是什么:>>>"Pythoncat"+666Traceback(mostrecentcalllast):File"",line1,inTypeError:canonlyconcatenatestr(not"int")tostr,报类型错误(TypeError),说字符串只能拼接(concatenate)字符串,不能拼接int类型。这是强类型语言的基本约束。但是,如果我们先把数字“转换”成字符串类型,再进行“+”操作,就不会报错了:>>>"Pythoncat"+str(666)'Pythoncat666'在上面例如,读者应该不难理解。由此,我们不得不提出一个问题:如何在不显式类型转换的情况下拼接字符串和数字?在《详解Python拼接字符串的七种方式》一文中,整理出了七种字符串的写法,大家可以一一尝试。几种字符串拼接方法:1、格式化:%、format()、template2。拼接:+、()、join()3、插值:f-string为了节省篇幅,这里我们可以直接将4种拼接方式罗列如下:>>>"%s%d"%("Pythoncat",666)'Pythoncat666'>>>fromstringimportTemplate>>>s=Template('${s1}${s2}')>>>s.safe_substitute(s1='Pythoncat',s2=666)'Python猫666'>>>"Python猫{}".format(666)'Python猫666'>>>num=666>>>f"Python猫{num}"'Python猫666'第一种写法(即%格式化)来自古老的C语言,其中“%d”是一个占位符,表示它会取一个整数并将其格式化为字符串。第二种和第三种写法是第一种写法的升级版。不同的是它们的占位符是通用的,不需要指定具体的类型,比如“%s”和“%d”。在这两种写法中,都是将数值类型的参数传递给具体的格式化方法(即safe_substitute和format),在这些方法内部,会进行类型转换处理。可以说,以上三种写法不难理解,其用意可循。不过现在看最后一种写法,也就是f-string的写法,好像不是那么明显。首先,在字符串内部,它没有指定像“%格式化”这样的占位符类型;第二,要拼接的数字不作为任何函数的参数传递。换句话说,根本没有执行类型转换的明显意图。但是,既然我们知道Python是强类型语言,那么已知的数值类型是绝对不可能直接拼接成字符串的。所以只能说明f-string语法在底层进行了某种类型转换操作!那么,我们可以提出一个新的问题:f-string语法在处理字符串和数字的时候是如何实现数字的类型转换的?有些读者可能会猜测它调用了内置的str()或repr()(或者它们对应的魔术方法\_\_str\_\_()和\_\_repr\_\_()),从而实现类型然而,转换,答案并不是那么简单!f-string语法是在Python3.6中引入的。为了省事,我们直接找到PEP-498文档,查进去看有没有实现原理的蛛丝马迹。文档地址:https://www.python.org/dev/pe...PEP中提到,f-string的语法格式如下:f'{}...'其中,花括号中的内容为需要格式化的内容。去掉可选的“optional”部分后,“expression”部分才是真正要处理的内容。对应前面的例子,数字666是一个表达式。表达式将根据\_\_format\_\_协议进行格式化,但不会直接调用\_\_format\_\_()方法。文档指出实际执行等同于type(value).__format__(value,format_spec)或format(value,format_spec)。实际上string对象的foramt()方法和Python内置的foramt()函数都会调用_\_format\_\_()魔术方法,所以f-string其实就是format()的格式化方法上一篇文章中的升级版.默认情况下,format_spec是一个空字符串,format(value,"")的效果等同于str(value)。所以,如果没有指定其他的format_spec,可以简单的认为是f-string调用了str()做类型转换……至此,我们已经看到了f-string的实现原理,明白了它在拼接的时候字符串和数字,其作用等同于前面的format()格式化方法,也等同于使用str()进行类型转换。写在最后:本文属于“WhyPython”系列(Python猫出品),主要关注Python的语法、设计、开发等话题。它以每一个“为什么”的问题为切入点,试图展示Python的魅力。魅力。更多精彩文章,请移步Github查看,项目地址:https://github.com/chinesehuazhou/python-whydo