一日一技:怎么你的字符串跟我不一样
如果你经常使用Python的命令行交互环境,你一定遇到过下面这个现象:
>>> a = 'test'
>>> a
'test'
>>> print(a)
test
首先定义一个变量a
,它的值为字符串test
。现在,当你在命令行交互环境直接输入变量名再回车的时候,你看到的是'test'
,当你输入print(a)
的时候,你看到的却是test
。
直接输入变量名回车,字符串会被单引号包起来。而使用print
函数打印变量,字符串又没有引号。
如果说引号只是一个小问题的话,再来看看反斜杠会怎么样:
>>> b = 'D:\game\pal4'
>>> b
'D:\\game\\pal4'
>>> print(b)
D:\game\pal4
在这里,b
变量的值为Windows下面的一个文件夹路径。在定义的时候,我使用的是单根反斜杠。
当我输入变量名,然后回车时,看到的结果是'D:\\game\\pal4'
,不仅有最外层的引号,而且反斜杠全部变成了两根。
但是当我使用print
函数打印出来的时候,一切又正常了。
觉得很诡异吗?
实际上,输入变量名,回车以后,你看到的才是这个字符串真正的样子,因为在Python里面是不存在单根反斜杠的。当你要表示反斜杠本身的时候,就应该是\\
这种写法。
当然在定义的时候你可以只写单根反斜杠,在大多数情况下,Python会理解你的意图,所以它会自动把单根反斜杠转换为两个反斜杠。
而使用print
关键字打印出来的,是经过Python优化,更便于人类阅读的样子。
当然,使用print
函数也能看到字符串真正的样子,不过需要修改一下:
>>> b = 'D:\game\pal4'
>>> b
'D:\\game\\pal4'
>>> print(repr(b))
'D:\\game\\pal4'
当你使用repr
函数先处理字符串,再打印时,它的效果就和直接输入变量名回车是一样的了。
在Python中,repr(对象)
本质上是调用了对象的__repr__
这个方法。而如果直接print(对象)
,实际上是打印了对象__str__
方法返回的内容。我们来做一个实验:
class Test:
def __repr__(self):
return 'hello world!'
def __str__(self):
return '为什么我总是对你说你好,因为你是我的世界啊,傻瓜'
you = Test()
动手测试一下,输入you
然后直接回车显示的是什么内容。输入print(you)
显示的又是什么内容。
运行效果如下图所示:
从上面的例子可以看出,直接输入变量名回车和直接用print
函数打印调用的是对象的不同方法。所以他们当然可以不一样。
回到昨天的问题上来。在PyCharm的调试模式中,你看到的内容实际上是变量对象的__repr__
方法返回的内容,这里的内容是字符串在Python里面的真正的样子,所以斜杠会变多。
上面说到,当你输入Windows路径的时候,大多数情况下,Python能够理解你的意图,把单根反斜杠转成双反斜杠。不过也有例外的情况,例如:假设有一个文件夹的名字叫做u6211
。它在pal4
文件夹里面。那么,路径应该是:D:\game\pal4\u6211
如果在Python里面执行,会出现什么问题?
>>> c = 'D:\game\pal4\u6211'
>>> c
'D:\\game\\pal4我'
>>> print(c)
D:\game\pal4我
怎么和前面的pal4拼在一起了?因为\u6211
是一个Unicode编码,表示中文我
。
这种情况下,你有两种解决方式:
-
手动使用双反斜杠:
>>> b = 'D:\game\pal4\\u6211'
>>> b
'D:\\game\\pal4\\u6211'
>>> print(b)
D:\game\pal4\u6211
-
在定义变量的时候,字符串左侧引号的左边加上字母 r
:
>>> b = r'D:\game\pal4\u6211'
>>> b
'D:\\game\\pal4\\u6211'
>>> print(b)
D:\game\pal4\u6211
- 点赞
- 收藏
- 关注作者
评论(0)