直接打印家庭表情符号,使用 U+200D 零宽度连接器,对比通过列表

Mic*_*mza 5 python unicode python-3.x emoji

在通过print直接打印带有家庭表情符号的字符串以及在列表中时,我发现了一些意想不到的差异。下面的程序

family = '???'
print(family)
print([family])
Run Code Online (Sandbox Code Playgroud)

产出

???
['\u200d\u200d\u200d']
Run Code Online (Sandbox Code Playgroud)

当我期望它输出时

???
['???']
Run Code Online (Sandbox Code Playgroud)

多字符字形的另一种情况

man_with_skin_tone_modifier = ''
print(man_with_skin_tone_modifier)
print([man_with_skin_tone_modifier])
Run Code Online (Sandbox Code Playgroud)

输出如我所料:


['']
Run Code Online (Sandbox Code Playgroud)

为什么是这样?


上下文:我在为/sf/answers/3495148191/编写答案时发现了这一点,它在 OS X 上使用 Python 3.6.5。

Uri*_*nta 2

正如注释中所指出的,区别在于print(family)调用该str.__str__方法,而print([family])调用str.__repr__则转义不可打印的 unicode 字符。

\n\n
    \n
  1. print函数使用 转换其(非关键字)参数str

  2. \n
  3. 调用str容器(通常)调用repr其项目。这主要是因为容器内的字符串很容易干扰容器本身的呈现(例如使用换行符)。围绕 Python 3 的发布,有人提出了改变这一点的 PEP,但很快就被拒绝了

  4. \n
  5. 调用repr字符串会转义任何不可打印的字符(但是,从 Python 3 开始,保留其他非 ASCII Unicode 字符):请参阅PEP-3138和str.isprintable的描述

  6. \n
\n\n
\n

如果字符串中的所有字符均可打印或字符串为空,则返回 true,否则返回 false。不可打印字符是在 Unicode 字符数据库中定义为 \xe2\x80\x9cOther\xe2\x80\x9d 或 \xe2\x80\x9cSeparator\xe2\x80\x9d 的字符,但被视为可打印的 ASCII 空格 (0x20) 除外。(请注意,此上下文中的可打印字符是在对 string 调用 repr() 时不应转义的字符。它与写入 sys.stdout 或 sys.stderr 的字符串的处理无关。)

\n
\n\n

CPython 实现可以在这里找到(搜索 unicode_repr 函数)。

\n