id() collisions on bound methods [was: metaclass and customization with parameters]
Jeff Epler
jepler at unpythonic.net
Tue Oct 5 20:08:29 EDT 2004
More information about the Python-list mailing list
Tue Oct 5 20:08:29 EDT 2004
- Previous message (by thread): id() collisions on bound methods [was: metaclass and customization with parameters]
- Next message (by thread): id() collisions on bound methods [was: metaclass and customization with parameters]
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
For an instance i with a method m, the expression 'i.m' *creates* (each time) a bound method object from i.__class__.m. >>> class C: ... def f(self): pass ... >>> c = C() >>> [c.f for i in range(3)] [<bound method C.f of <__main__.C instance at 0xf6f7488c>>, <bound method C.f of <__main__.C instance at 0xf6f7488c>>, <bound method C.f of <__main__.C instance at 0xf6f7488c>>] >>> [id(m) for m in _] # All distinct [-151250548, -151134580, -151178020] >>> id(c.f) # Same as "first one" from earlier. -151250548 In your example, the bound method 'mc.method0' can be discarded (it is no longer referencable) before the next statement, so it is possible for the result of the next expression to have the same id(). The same goes for the last 'id(c.f)' line, all the bound methods created in the [c.f] listcomp are unreachable, and objects with the same id can now be created. Here's another one for you: >>> id(200) 138049956 >>> id(300) 138049956 >>> id(400) 138049956 Again, the integer in each expression can be discarded, so it is possible for an object with the same id to be created in a later expression. Python guarantees that two distinct objects alive *at the same time* have different ids. Each of these examples has objects with dijoint lifetimes. Now, the next thing you may run in to is that immutable objects are never guaranteed to be distinct. Sometimes they are, sometimes they aren't. Here are some actual examples from Python 2.3.3: >>> (1,) is (1,) # Only the empty tuple is special (may differ in 2.4) False >>> x = 100 # small integer cache doesn't go this high >>> y = 100 >>> x is y False >>> 50 * 2 is 50 * 2 # Same principle as above False >>> x = "rhubarb" # string literals are interned, but result of + is not >>> "rhu" + "barb" is x False >>> () is () # Empty tuple is a special case True >>> 100 is 100 # Because 100 is in the bytecode's constants True >>> 2 * 2 is 2 * 2 # Because 4 is in the small integer cache True >>> x = "rhubarb" # Because both strings are literals >>> y = "rhubarb" >>> x is y True For each of these sequences, Python is free to print either 'True' or 'False' (because they deal with the distinctness of immutable objects) and the actual result depends on implementation choices of CPython 2.3.3. Jeff -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 196 bytes Desc: not available URL: <http://mail.python.org/pipermail/python-list/attachments/20041005/055d0cda/attachment.sig>
- Previous message (by thread): id() collisions on bound methods [was: metaclass and customization with parameters]
- Next message (by thread): id() collisions on bound methods [was: metaclass and customization with parameters]
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list