2011-06-02 68 views
2
class Bar: 
    pass 

class Foo: 
    def __str__(self): return "Foo instance" 

>> aBar = Bar() 
>> print aBar 
<__main__.Bar instance at 0x100572a28> 
>> aFoo = Foo() 
>> print aFoo 
Foo instance 

重写__str__方法后,有没有办法重写STR方法后,打印出aFoo的地址?你如何获得一个实例的地址在python

使用

>>repr(aFoo) 

解决我的问题

回答

6

至少在CPython的,id提供地址。但输出是十进制的;你必须将其转换为十六进制:

>>> f = (x for x in [1,2,3]) 
>>> print f 
<generator object <genexpr> at 0x1004d22d0> 
>>> '%x' % id(f) 
'1004d22d0' 

事实上,虽然,__repr__功能并不时__str__被覆盖改变。所以,你可以这样做,以及:

>>> class Foo: 
...  def __str__(self): return "Foo instance" 
... 
>>> a = Foo() 
>>> print a 
Foo instance 
>>> print repr(a) 
<__main__.Foo instance at 0x1004d1c68> 

我觉得id优选的是,这一点,如果你想要的是真正的id。但id不保证返回地址;这只是cpython的实现。我不知道是否指定了对象的内置__repr__必须返回地址,还是必须返回id,或者都不返回。所以,如果你特别想要__repr__提供的东西,那么这可能是一条可行的路。

更新:答案是既不,至少根据language reference,只决定了对象的__repr__是“和明确的信息丰富的。”事实上,有时__repr__实际上并不返回有问题的特定对象的地址,在这里看到:

>>> a = Foo() 
>>> '%x' % id(a) 
'1004d1fc8' 
>>> '%x' % id(a.__str__) 
'1004745a0' 
>>> '%x' % id(Foo.__str__) 
'1004745a0' 
>>> repr(a.__str__) 
'<bound method Foo.__str__ of <__main__.Foo instance at 0x1004d1fc8>>' 
+0

.NET的对象没有一个固定的地址,所以没有办法了IronPython的再版可包括一个地址:.Net垃圾回收会移动对象,这样可用内存几乎是连续的。我不确定Jython,但它可能是一样的。 – Duncan 2011-06-02 20:43:54

+0

@Duncan,我也这么想。没有要测试的IronPython安装,IronPython在默认'__repr__'方法中提供了什么?它是否与'id'返回的值相同? – senderle 2011-06-02 21:53:25

+0

是的,它是'id()'返回的值,但只有在调用id()后才会分配id,并且是一个简单的递增计数。例如,我创建了一个类的4个实例(a,b,c,d),然后以任意顺序(d,b,c,a)打印它们的'repr()',并且这些id与我打印它们的顺序相匹配:id(a),id(b),id(c),id(d)'给出'(48,46,47,45)'。 – Duncan 2011-06-03 08:40:50