python中的反引号reverse quotes

  • Shuwei Zhang & Jinhai ZHOU
  • 7 Minutes
  • 2017年9月25日

目录

反引号`

今天在看一本基于python2.2的Design Pattern书,其中有一段关于单例的代码我很不解,因为用到了反引号`,也就是reverse quotes。书中代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class OnlyOne:
class __OnlyOne:
def __init__(self, arg):
self.val = arg
def __str__(self):
return `self` + self.val
instance = None
def __init__(self, arg):
if not OnlyOne.instance:
OnlyOne.instance = OnlyOne.__OnlyOne(arg)
else:
OnlyOne.instance.val = arg
def __getattr__(self, name):
return getattr(self.instance, name)
x = OnlyOne('sausage')
print x
y = OnlyOne('eggs')
print y
z = OnlyOne('spam')
print z
print x
print y
print `x`
print `y`
print `z`

console输出结果是

1
2
3
4
5
6
7
8
<__builtin__.__OnlyOne instance at 0x7ff4670b0200>sausage
<__builtin__.__OnlyOne instance at 0x7ff4670b0200>eggs
<__builtin__.__OnlyOne instance at 0x7ff4670b0200>spam
<__builtin__.__OnlyOne instance at 0x7ff4670b0200>spam
<__builtin__.__OnlyOne instance at 0x7ff4670b0200>spam
<__builtin__.OnlyOne instance at 0x7ff4670b01b8>
<__builtin__.OnlyOne instance at 0x7ff4670b0290>
<__builtin__.OnlyOne instance at 0x7ff4670b02d8>

反引号`到底有什么用呢?经过查询,反引号在python2中是repr()函数的别名(alias),但是反引号别名表示已经在pyhton3.0中取消了。至于为何取消,Guido van Rossum他本人的解释是反引号`和正常引号‘的相似性实在是太令人误解了,此外反引号在印刷字体以及输入方面都有不少问题。

repr函数

知道了python中反引号`其实是repr()函数的别名,那么python中repr函数本身又是干什么的呢?

repr(object)
Return a string containing a printable representation of an object. This is the same value yielded by conversions (reverse quotes). It is sometimes useful to be able to access this operation as an ordinary function. For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a repr() method.

根据上述节选自python官方文档的解释,可以知道repr函数主要功能是返回object的一种可打印字符串表示。一般来说,repr函数被设计成其输出可以被eval函数生成值相同的object,或者,被设计成返一个包含在尖头括号中的字符串,其中包含对象类型名称和一些附加信息。而附加信息通常包括这个对象的名字和物理地址。

在Desgin Patter作者给出的单例代码中,repr函数便输出了对象的名字和物理地址。

关于单例的思考

一般讲Desgin Pattern的书几乎一开始都会讲单例,毕竟单例是最容易理解的Desgin Pattern。作者在实现单例时用了nested class方法,内部class是一个私有class,这样外部无法直接访问。那么print函数又是如何访问到私有class的__str__函数的呢?这就要靠wrapper class的__getattr__函数了,在这里作者巧妙实现了一个delegation。这也是为什么print OnlyOne class的instance时,console输出都是私有class的__str__函数定义的结果。

参考

  1. What do backticks mean to the python interpreter: num
  2. [Python-ideas] new operators via backquoting
  3. docs.python repr(object)
  4. Bruce Eckel Thinking in Python