Re: Is there an official way to add methods to an instance?

2008-04-08 Thread [EMAIL PROTECTED]
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?

2008-04-08 Thread méchoui
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?

2008-04-04 Thread Charles Mason
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?

2008-04-04 Thread John Nagle
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?

2008-04-04 Thread Bruno Desthuilliers
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?

2008-04-04 Thread Bruno Desthuilliers
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?

2008-04-04 Thread Paul Rubin
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?

2008-04-04 Thread Peter Otten
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?

2008-04-03 Thread Gabriel Genellina
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?

2008-04-03 Thread Gabriel Genellina
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?

2008-04-03 Thread Roger Miller
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?

2008-04-03 Thread Brian Vanderburg II
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