Re: Is there an official way to add methods to an instance?
On 8 avr, 11:39, méchoui <[EMAIL PROTECTED]> wrote: > On Apr 4, 5:25 pm, John Nagle <[EMAIL PROTECTED]> wrote: > > > > > Bruno Desthuilliers wrote: > > > Paul Rubin a écrit : > > >> Brian Vanderburg II <[EMAIL PROTECTED]> writes: > > >>> I've checked out some ways to get this to work. I want to be able to > > >>> add a new function to an instance of an object. > > > >> Ugh. Avoid that if you can. > > > > Why so ? OO is about objects, not classes, and adding methods on a > > > per-object basis is perfectly legitimate. > > > It's what professional programmers call a "l33t feature", > > one not suitable for production code. Typically such features > > are used by programmers with about two years experience, > > trying too hard to prove that they're cool. @john: I've ten years of experience, definitively don't care about looking "cool" or "l33t", and sorry, but I won't buy your purely ideological arguments. This reminds me of the lead engineer in one of my first job forbidding using OO because he didn't get it, or some Java guy trying to convince me that a language with dynamic typing and no access restriction could not be used for "production code". > > John Nagle > > Yes, and the reason is quite obvious: if you read the code of the > class, you can't see the function. That makes it much more difficult > to understand and to debug. Then we should forbid inheritence - you don't see the inherited functions when reading the code of the class. And we should forbid monkey-patching, metaclasses and quite a lot of other things as well. And also, we should go back to static typing - with dynamic typing, you don't know by reading the signature of a function what kind of arguments it expects. C'mon, be serious guys. As everything else, the problem is not with the feature, but with knowing how to properly use it and how to not abuse it. If you don't trust the programmer, then don't use a dynamic language. You know where to find Java and Ada... -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there an official way to add methods to an instance?
On Apr 4, 5:25 pm, John Nagle <[EMAIL PROTECTED]> wrote: > Bruno Desthuilliers wrote: > > Paul Rubin a écrit : > >> Brian Vanderburg II <[EMAIL PROTECTED]> writes: > >>> I've checked out some ways to get this to work. I want to be able to > >>> add a new function to an instance of an object. > > >> Ugh. Avoid that if you can. > > > Why so ? OO is about objects, not classes, and adding methods on a > > per-object basis is perfectly legitimate. > > It's what professional programmers call a "l33t feature", > one not suitable for production code. Typically such features > are used by programmers with about two years experience, > trying too hard to prove that they're cool. > > John Nagle Yes, and the reason is quite obvious: if you read the code of the class, you can't see the function. That makes it much more difficult to understand and to debug. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there an official way to add methods to an instance?
And for such a behavior they've termed "monkeying" Thus, the coinage "Monkeypatching" for what you want to do: http://mail.python.org/pipermail/python-dev/2008-January/076194.html There are a group of people who think "monkeypatching is destroying ruby." You still probably should avoid it for production code. On Fri, Apr 4, 2008 at 11:25 AM, John Nagle <[EMAIL PROTECTED]> wrote: > Bruno Desthuilliers wrote: > > Paul Rubin a écrit : > >> Brian Vanderburg II <[EMAIL PROTECTED]> writes: > >>> I've checked out some ways to get this to work. I want to be able to > >>> add a new function to an instance of an object. > >> > >> Ugh. Avoid that if you can. > > > > Why so ? OO is about objects, not classes, and adding methods on a > > per-object basis is perfectly legitimate. > >It's what professional programmers call a "l33t feature", > one not suitable for production code. Typically such features > are used by programmers with about two years experience, > trying too hard to prove that they're cool. > >John Nagle > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there an official way to add methods to an instance?
Bruno Desthuilliers wrote: > Paul Rubin a écrit : >> Brian Vanderburg II <[EMAIL PROTECTED]> writes: >>> I've checked out some ways to get this to work. I want to be able to >>> add a new function to an instance of an object. >> >> Ugh. Avoid that if you can. > > Why so ? OO is about objects, not classes, and adding methods on a > per-object basis is perfectly legitimate. It's what professional programmers call a "l33t feature", one not suitable for production code. Typically such features are used by programmers with about two years experience, trying too hard to prove that they're cool. John Nagle -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there an official way to add methods to an instance?
Peter Otten a écrit : (snip) > Anyway, here is one more option to add too the zoo: > class A(object): > ... def __init__(self, f, x): > ... self._f = f > ... self.x = x > ... @property > ... def f(self): > ... return self._f.__get__(self) > ... def __del__(self): > ... print "deleting" > ... This is nice but requires that you know in advance how many methods you're going to add and how they will be named (which is not a bad thing in itself - on the contrary - but may not be what the OP is after), and that you can add these methods at instanciation time. A variant could be: class A(object): def __init__(self, x): self.x = x def __getattr__(self, name): target = '_' + name # avoids recursion if hasattr(self, target): func = getattr(self, target) if hasattr(func, '__get__'): return func.__get__(self, type(self)) # nothing found, bye... raise AttributeError( "%s object has no attribute %s" % (self, name) ) a = A(21) a._foo = lambda self: "answer is %s" % (self.x * 2) print a.foo() -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there an official way to add methods to an instance?
Paul Rubin a écrit : > Brian Vanderburg II <[EMAIL PROTECTED]> writes: >> I've checked out some ways to get this to work. I want to be able to >> add a new function to an instance of an object. > > Ugh. Avoid that if you can. Why so ? OO is about objects, not classes, and adding methods on a per-object basis is perfectly legitimate. > But see: > > http://en.wikipedia.org/wiki/Monkey_patch Adding methods on a per-object basis is not monkey patching (as defined in the above article and as usually understood here) and doesn't address the same class (no pun intended) of problems. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there an official way to add methods to an instance?
Brian Vanderburg II <[EMAIL PROTECTED]> writes: > I've checked out some ways to get this to work. I want to be able to > add a new function to an instance of an object. Ugh. Avoid that if you can. But see: http://en.wikipedia.org/wiki/Monkey_patch -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there an official way to add methods to an instance?
Brian Vanderburg II wrote: > I don't know if this is the correct place to send this question. It is. > I've checked out some ways to get this to work. I want to be able to > add a new function to an instance of an object. I've tested two > different methods that cause problems with 'deleting'/garbage collection > (__del__ may never get called), but implemented one sort of hackishly > maybe that works find. I'm wondering if there is more of an official way > than mine. [snip] I think "Try hard to avoid __del__()" is as close to an official stance as you can get ;) Anyway, here is one more option to add too the zoo: >>> class A(object): ... def __init__(self, f, x): ... self._f = f ... self.x = x ... @property ... def f(self): ... return self._f.__get__(self) ... def __del__(self): ... print "deleting" ... >>> a = A(lambda s: s.x * 2, 2) >>> b = A(lambda s: s.x * 3, 3) >>> a.f() 4 >>> b.f() 9 >>> del a deleting >>> del b deleting Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there an official way to add methods to an instance?
En Thu, 03 Apr 2008 22:43:30 -0300, Roger Miller <[EMAIL PROTECTED]> escribió: > On Apr 3, 2:57 pm, Brian Vanderburg II <[EMAIL PROTECTED]> > wrote: >> >> I've checked out some ways to get this to work. I want to be able to >> add a new function to an instance of an object. I've tested two >> different methods that cause problems with 'deleting'/garbage collection >> (__del__ may never get called), but implemented one sort of hackishly >> maybe that works find. I'm wondering if there is more of an official way >> than mine. >> > > Maybe I'm missing something, but the boring old straightforward > approach works for me: > > class A: > def __del__(self): > print "Deleting" > > def f(x): > print x > > a = A() > a.f = f > a.f(42) > del a This doesn't create an instance method. You can't access `a` (as `self`) from inside f. -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there an official way to add methods to an instance?
En Thu, 03 Apr 2008 21:57:56 -0300, Brian Vanderburg II <[EMAIL PROTECTED]> escribió: > I don't know if this is the correct place to send this question. > > I've checked out some ways to get this to work. I want to be able to > add a new function to an instance of an object. I've tested two > different methods that cause problems with 'deleting'/garbage collection > (__del__ may never get called), but implemented one sort of hackishly > maybe that works find. I'm wondering if there is more of an official way > than mine. > > 1. > import new > import gc > > class A: > def __del__(x): >print "Deleting" > > def f(x): > print x > > a = A() > a.f = new.instancemethod(a,f) > a.f() # This works > del a # Not what is expected > gc.collect() # Works, but __del__ does not get called O thou of little faith, wherefore didst thou doubt? This is the simplest and preferred way, and it works! It's true that there is a reference cycle between a and a.f, but the garbage collector is able to detect it and dispose of those objects *UNLESS* any of them contains a __del__ method written in Python. See http://docs.python.org/ref/customization.html So this *is* the right way, and the object `a` would have been deleted if you had not tried to witness the deletion itself... You perturbed the system in a non trivial way just by attempting to observe it - isn't this Quantum Mechanics applied to Python programming? We need a side-effect triggered by __del__ but written in C... hmmm, what about flushing a file buffer? py> import new py> import gc py> import os py> py> class myfile(file): # just to be able to add attributes ... pass ... py> def f(x): ... print x ... py> a = myfile("a.aaa","w") py> print os.stat("a.aaa").st_size # 0 0 py> a.f = new.instancemethod(f, a) py> a.f() # This works py> a.write("X") # a single char, should stay on write buffer py> print os.stat("a.aaa").st_size # still 0 0 py> del a py> print os.stat("a.aaa").st_size # still 0 0 py> gc.collect() 3 py> print os.stat("a.aaa").st_size # now 1 1 -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there an official way to add methods to an instance?
On Apr 3, 2:57 pm, Brian Vanderburg II <[EMAIL PROTECTED]> wrote: > > I've checked out some ways to get this to work. I want to be able to > add a new function to an instance of an object. I've tested two > different methods that cause problems with 'deleting'/garbage collection > (__del__ may never get called), but implemented one sort of hackishly > maybe that works find. I'm wondering if there is more of an official way > than mine. > Maybe I'm missing something, but the boring old straightforward approach works for me: class A: def __del__(self): print "Deleting" def f(x): print x a = A() a.f = f a.f(42) del a Output: 42 Deleting -- http://mail.python.org/mailman/listinfo/python-list
Is there an official way to add methods to an instance?
I don't know if this is the correct place to send this question. I've checked out some ways to get this to work. I want to be able to add a new function to an instance of an object. I've tested two different methods that cause problems with 'deleting'/garbage collection (__del__ may never get called), but implemented one sort of hackishly maybe that works find. I'm wondering if there is more of an official way than mine. 1. import new import gc class A: def __del__(x): print "Deleting" def f(x): print x a = A() a.f = new.instancemethod(a,f) a.f() # This works del a # Not what is expected gc.collect() # Works, but __del__ does not get called 2. import gc def addmethod(self,func,name): def wrapper(*args,**kwargs): return func(self,*args,**kwargs) setattr(self,name,func) class A: def __del__(x): print "Deleting" def f(x): print x a = A() addmethod(a, f, "f") a.f() # Works as expected del a # nope gc.collect() # Still __del__ doesn't get called 3. Slightly hackish method, maybe some problems import gc import weakref def addmethod(self,func,name): # change the value of 'self' so wrapper.func_globals will reference the new value self = weakref.ref(self) def wrapper(*args,**kwargs): return func(self(),*args,**kwargs) setattr(self(),name,func) class A: def __del__(x): print "Deleting" def f(x): print x a = A() addmethod(a, f, "f") a.f() # Works as expected del a gc.collect() With this method 'del a' does the expected most of the time, and "Deleting" does get printed or when calling 'gc.collect()' it prints correctly. This seems the best approach so that when 'a' is no longer valid, the object can die instead of continuing to exitng because wrapper.func_globals still contains a reference, but seems very hackish an maybe problematic. I'm wondering if there is a better way? Brian Vanderburg II -- http://mail.python.org/mailman/listinfo/python-list