Re: question about the id()
Giovanni Bajo [EMAIL PROTECTED] writes: Peter Dembinski wrote: BTW, a typical performance optimization (not done automatically by python) is to hoist unchanging-value expressions out of loops, and obj.method is often such an expression, so you will this strategy when people try to squeeze extra performance from their programs. Good to know. Is there any advanced optimizer for Python code, which would do such things for me (or suggest them, like pychecker does for readability)? Prove that a.f() would not change the meaning of a.f after its invokation is close to impossible. Many things in Python programs cannot be proved. But what about suggesting optimisations, not doing them automatically? The similar case may be found in refactorization -- most things cannot be proved, so the final decision is left to the programmer (and his unit tests). -- http://www.peter.dembinski.prv.pl -- http://mail.python.org/mailman/listinfo/python-list
Re: question about the id()
On Tue, 17 May 2005 13:56:18 +0200, Peter Dembinski [EMAIL PROTECTED] wrote: Giovanni Bajo [EMAIL PROTECTED] writes: Peter Dembinski wrote: BTW, a typical performance optimization (not done automatically by python) is to hoist unchanging-value expressions out of loops, and obj.method is often such an expression, so you will this strategy when people try to squeeze extra performance from their programs. Good to know. Is there any advanced optimizer for Python code, which would do such things for me (or suggest them, like pychecker does for readability)? Prove that a.f() would not change the meaning of a.f after its invokation is close to impossible. Many things in Python programs cannot be proved. But what about suggesting optimisations, not doing them automatically? At that point, you can do the optimization yourself: class A: def method( self ): pass a = A( ) m = a.method # optimize runtime lookups for a.method for x in range( 10 ): m( ) Regards, Dan -- Dan Sommers http://www.tombstonezero.net/dan/ -- http://mail.python.org/mailman/listinfo/python-list
Re: question about the id()
kyo guan wrote: Can someone explain why the id() return the same value, and why these values are changing? Thanks you. a=A() id(a.f) 11365872 id(a.g) 11365872 The Python functions f and g, inside of a class A, are unbound methods. When accessed through an instance what's returned is a bound method. A.f unbound method A.f A().f bound method A.f of __main__.A instance at 0x64198 In your code you do a.f, which creates a new bound method. After the id() call its ref-count goes to zero and its memory is freed. Next you do a.g which creates a new bound method. In this case it reuses the same memory location, which is why you get the same id. I know Python keeps free lists for some data types. I suspect bound method objects are tracked this way because they are made/destroyed so frequently. That would increase the likelihood of you seeing the same id value. a.f is a.g False This is the first time you have two bound methods at the same time. Previously a bound method was garbage collected before the next one was created. id(a.f), id(a.g), id(b.f), id(b.g) (11492408, 11492408, 11492408, 11492408) a.f is a.g False id(a.f), id(a.g), id(b.f), id(b.g) (11365872, 11365872, 11365872, 11365872) The memory locations changed. Here's a conjecture that fits the facts and is useful to help understand. Suppose the free list is maintained as a stack, with the most recently freed object at the top of the stack, which is the first to be used for the next object. The a.f is a.g creates two bound methods, one at 11492408 and the other at 11365872. Once the 'is' is done it dec-refs the two methods, a.f first and a.g second. In this case the ref counts go to zero and the memory moved to the free list. At this point the stack looks like [11365872, 11492408, ... rest of stack ... ] You then do a.f. This pulls from the top of the stack so you get 11365872 again. The id() tells you that, and then the object gets decrefed and put back on the stack. Andrew [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: question about the id()
Skip Montanaro [EMAIL PROTECTED] writes: kyo Can someone explain why the id() return the same value, and kyo why these values are changing? Instance methods are created on-the-fly. So, the interpreter creates new 'point in address space' every time there is object-dot-method invocation in program? -- http://www.peter.dembinski.prv.pl -- http://mail.python.org/mailman/listinfo/python-list
Re: question about the id()
Peter Dembinski wrote: So, the interpreter creates new 'point in address space' every time there is object-dot-method invocation in program? Yes. That's why some code hand-optimizes inner loops by hoisting the bound objection creation, as data = [] data_append = data.append for x in some_other_data: work with x to make y data_append(y) Andrew [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: question about the id()
On Mon, 16 May 2005 18:30:47 +0200, Peter Dembinski [EMAIL PROTECTED] wrote: Skip Montanaro [EMAIL PROTECTED] writes: kyo Can someone explain why the id() return the same value, and kyo why these values are changing? Instance methods are created on-the-fly. So, the interpreter creates new 'point in address space' every time there is object-dot-method invocation in program? Yes, but you can save the result of the obj.method expression (that's what it is, an expression). E.g., bound_method = obj.method after that, you can write bound_method() or obj.method() (of course, you can pass arguments too, depending on the signature, remembering that the self instance parameter is already bound in and does not need to be passed again to a bound method) The obj.method() call will re-evaluate the obj.method expression, and the bound_method() call will just call the previously created bound method. BTW, a typical performance optimization (not done automatically by python) is to hoist unchanging-value expressions out of loops, and obj.method is often such an expression, so you will this strategy when people try to squeeze extra performance from their programs. Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list
Re: question about the id()
On Mon, 16 May 2005 16:57:12 GMT, Andrew Dalke [EMAIL PROTECTED] wrote: Peter Dembinski wrote: So, the interpreter creates new 'point in address space' every time there is object-dot-method invocation in program? Yes. That's why some code hand-optimizes inner loops by hoisting the bound objection creation, as data = [] data_append = data.append for x in some_other_data: work with x to make y data_append(y) Sorry about the me-too. I hadn't seen your post. I should know better ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list
Re: question about the id()
[EMAIL PROTECTED] (Bengt Richter) writes: [snap] So, the interpreter creates new 'point in address space' every time there is object-dot-method invocation in program? [optimization] BTW, a typical performance optimization (not done automatically by python) is to hoist unchanging-value expressions out of loops, and obj.method is often such an expression, so you will this strategy when people try to squeeze extra performance from their programs. Good to know. Is there any advanced optimizer for Python code, which would do such things for me (or suggest them, like pychecker does for readability)? -- http://www.peter.dembinski.prv.pl -- http://mail.python.org/mailman/listinfo/python-list
Re: question about the id()
Peter Dembinski wrote: BTW, a typical performance optimization (not done automatically by python) is to hoist unchanging-value expressions out of loops, and obj.method is often such an expression, so you will this strategy when people try to squeeze extra performance from their programs. Good to know. Is there any advanced optimizer for Python code, which would do such things for me (or suggest them, like pychecker does for readability)? Prove that a.f() would not change the meaning of a.f after its invokation is close to impossible. -- Giovanni Bajo -- http://mail.python.org/mailman/listinfo/python-list
question about the id()
HI ALL: Can someone explain why the id() return the same value, and why these values are changing? Thanks you. Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32 Type help, copyright, credits or license for more information. class A(object): ... def f(): ... pass ... def g(): ... pass ... a=A() id(a.f) 11365872 id(a.g) 11365872 class B(object): ... def f(): ... print 1 ... def g(): ... print 3 ... b=B() id(b.f) 11365872 id(b.g) 11365872 id(a.f), id(a.g), id(b.f), id(b.g) (11365872, 11365872, 11365872, 11365872) a.f is a.g False id(a.f), id(a.g), id(b.f), id(b.g) (11492408, 11492408, 11492408, 11492408) a.f is a.g False id(a.f), id(a.g), id(b.f), id(b.g) (11365872, 11365872, 11365872, 11365872) -- http://mail.python.org/mailman/listinfo/python-list
Re: question about the id()
kyo Can someone explain why the id() return the same value, and why kyo these values are changing? Instance methods are created on-the-fly. In your example the memory associated with the a.f bound method (not the same as the unbound method A.f) is freed before you reference a.g. That chunk of memory just happens to get reused for the bound method associated with a.g. Here's a demonstration: % python Python 2.5a0 (#77, May 14 2005, 14:47:06) [GCC 3.3 20030304 (Apple Computer, Inc. build 1671)] on darwin Type help, copyright, credits or license for more information. class A(object): ... def f(): pass ... def g(): pass ... a = A() x = a.f y = a.g id(x) 17969240 id(y) 17969440 id(a.f) 17969400 id(a.g) 17969400 Skip -- http://mail.python.org/mailman/listinfo/python-list
RE: question about the id()
HI Skip: I want to check is there any change in the instance 's methods. a=A() a2=A() a.f == a2.f False a.f is a2.f False a.f is a.f False If the instance methods are create on-the-fly, how to do that? Thanks. Kyo -Original Message- From: Skip Montanaro [mailto:[EMAIL PROTECTED] Sent: Monday, May 16, 2005 11:09 AM To: kyo guan Cc: python-list@python.org Subject: Re: question about the id() kyo Can someone explain why the id() return the same value, and why kyo these values are changing? Instance methods are created on-the-fly. In your example the memory associated with the a.f bound method (not the same as the unbound method A.f) is freed before you reference a.g. That chunk of memory just happens to get reused for the bound method associated with a.g. Here's a demonstration: % python Python 2.5a0 (#77, May 14 2005, 14:47:06) [GCC 3.3 20030304 (Apple Computer, Inc. build 1671)] on darwin Type help, copyright, credits or license for more information. class A(object): ... def f(): pass ... def g(): pass ... a = A() x = a.f y = a.g id(x) 17969240 id(y) 17969440 id(a.f) 17969400 id(a.g) 17969400 Skip -- http://mail.python.org/mailman/listinfo/python-list
Re: question about the id()
On Mon, 16 May 2005 11:28:31 +0800, kyo guan [EMAIL PROTECTED] wrote: HI Skip: I want to check is there any change in the instance 's methods. a=A() a2=A() a.f == a2.f False a.f is a2.f False a.f is a.f False If the instance methods are create on-the-fly, how to do that? Thanks. You have to define exactly what you mean by the instance's methods first ;-) a.f is an expression that when evaluated creates a bound method according to the rules of doing that. You can check what function was found for creating this bound method using the .im_func attribute -- i.e. a.f.im_func -- but that is only valid for that particular bound method. A bound method is a first class object that you can pass around or assign, so the function you might get from a fresh a.f might differ from a previous a.f, e.g., class A(object): ... def f(self): return 'f1' ... a=A() a2=A() a.f.im_func is a2.f.im_func True Now save the bound method a.f af = a.f And change the class A method A.f = lambda self: 'f2' Both a and a2 dynamically create bound methods based on the new method (lambda above) so the functions are actually the same identical one a.f.im_func is a2.f.im_func True But the bound method we saved by binding it to af still is bound to the old method function, so a new dynamically created one is not the same: af.im_func is a2.f.im_func False af.im_func function f at 0x02FA3CDC a.f.im_func function lambda at 0x02F99B1C a2.f.im_func function lambda at 0x02F99B1C The .im_func function id's are shown in hex through the repr above. I.e., compare with: '0x%08X' % id(a2.f.im_func) '0x02F99B1C' '0x%08X' % id(af.im_func) '0x02FA3CDC' HTH Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list