Re: adding methods at runtime

2008-01-11 Thread Bruno Desthuilliers
[EMAIL PROTECTED] a écrit :
> Can I access the class attributes from a method added at runtime? 

Of course.

> (My
> experience says no.)

So there's something wrong with your experience !-)

> I experimented with the following code:
> 
> 
> class myclass(object):
> myattr = "myattr"
> 
> instance = myclass()
> def method(x):
> print x
> 
> instance.method = method

As Marc pointed out, you're not adding a method but a function. What you 
want is:

def method(self, x):
   print "x : %s - myattr : %s" % (x, self.myattr)

import new
instance.method = new.instancemethod(method, instance, myclass)

Note that this is only needed for per-instance methods - if you want to 
add a new method for all instances, you just set the function as 
attribute of the class. The lookup mechanism will then invoke the 
descriptor protocol on the function object, which will return a method 
(FWIW, you have to do it manually on per-instance methods because the 
descriptor protocol is not invoked on instance attributes, only on class 
attributes).

HTH
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime

2008-01-11 Thread John Machin
On Jan 11, 10:44 am, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote:
> On Thu, 10 Jan 2008 14:55:18 -0800, [EMAIL PROTECTED] wrote:
> > Can I access the class attributes from a method added at runtime? (My
> > experience says no.)
> > I experimented with the following code:
>
> > [Code snipped]
>
> > So it seems to me, if you add a method to an instance, the method will
> > not get "self" as parameter.
>
> You are not adding a method but a function.  Take a look at
> `types.MethodType()` to create a method from a function, instance, and
> class.
>

Just in case gentle readers are wondering where to find the docs for
types.MethodType, here's a hint:

>>> import types, new; types.MethodType is new.instancemethod
True
>>>


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime

2008-01-10 Thread Marc 'BlackJack' Rintsch
On Thu, 10 Jan 2008 14:55:18 -0800, [EMAIL PROTECTED] wrote:

> Can I access the class attributes from a method added at runtime? (My
> experience says no.)
> I experimented with the following code:
> 
> [Code snipped]
> 
> So it seems to me, if you add a method to an instance, the method will
> not get "self" as parameter.

You are not adding a method but a function.  Take a look at
`types.MethodType()` to create a method from a function, instance, and
class.

Ciao,
Marc 'BlackJack' Rintsch
-- 
http://mail.python.org/mailman/listinfo/python-list


adding methods at runtime

2008-01-10 Thread [EMAIL PROTECTED]
Can I access the class attributes from a method added at runtime? (My
experience says no.)
I experimented with the following code:


class myclass(object):
myattr = "myattr"

instance = myclass()
def method(x):
print x

instance.method = method
instance.method("hello world")

inst2 = myclass()
#inst2.method("inst2")

def meth2(x):
print x.myattr

myclass.ujmeth = meth2
inst2 = myclass()
inst2.ujmeth()



The output:
##

hello world
myattr



So it seems to me, if you add a method to an instance, the method will
not get "self" as parameter.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime and lambda

2007-05-07 Thread Mike
On May 4, 5:46 pm, Peter Otten <[EMAIL PROTECTED]> wrote:
> Mike wrote:
> > I just realized in working with this more that the issues I was having
> > with instancemethod and other things seems to be tied solely to
>
> What you describe below is a function that happens to be an attribute of an
> instance. There are also "real" instance methods that know about "their"
> instance:
>
> >>> import new
> >>> class A(object):
>
> ... def __init__(self, name):
> ... self.name = name
> ...>>> def method(self): # a function...
>
> ... print self.name
> ...>>> a = A("alpha")
> >>> b = A("beta")
> >>> a.method = new.instancemethod(method, a) # ...turned into a method...
> >>> a.method()
> alpha
> >>> b.method() # ... but only known to a specific instance of A
>
> Traceback (most recent call last):
>   File "", line 1, in 
> AttributeError: 'A' object has no attribute 'method'
>
> > builtins like dict or object. I remember at some point just doing
> > something like:
>
> > x.fn = myfnFunction
>
> > and having it just work.
>
> With the caveat that x.fn is now an alias for myfnFunction, but doesn't get
> x passed as its first argument (conventionally named 'self') and therefore
> has no knowledge of the instance x.
>
>
>
> > If I do that with an instance of generic
> > object however, I get an AttributeError. So:
>
> > x = object()
> > x.fn = myFn
>
> > blows up. However, if I do
>
> > class nc(object):pass
> > x = nc()
> > x.fn = myFn
>
> > Then all is well.
>
> > checking for an ability on somebody is as simple as
>
> > 'fn' in dir(x)
>
> > or
>
> > hasattr(x, 'fn')
>
> > I had thought this was a lot easier than I was making it out to be.
> > What I don't know is why using an object derived from object allows
> > you to dynamically add methods like this but the base object does not.
> > At this point it is more of a curiosity than anything, but if somebody
> > knows the answer off the top of their head, that would be great.
>
> Arbitrary instance attributes are implemented via a dictionary (called
> __dict__), and that incurs a certain overhead which is sometimes better to
> avoid (think gazillion instances of some tiny class). For example, tuples
> are derived from object but don't have a __dict__.
> As a special case, what would happen if dict were to allow attributes? It
> would need a __dict__ which would have a __dict__ which would have...
> As a consequence object could no longer be the base class of all (newstyle)
> classes.
>
> Peter

Thanks.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime and lambda

2007-05-04 Thread Peter Otten
Mike wrote:

> I just realized in working with this more that the issues I was having
> with instancemethod and other things seems to be tied solely to

What you describe below is a function that happens to be an attribute of an
instance. There are also "real" instance methods that know about "their"
instance:

>>> import new
>>> class A(object):
... def __init__(self, name):
... self.name = name
...
>>> def method(self): # a function...
... print self.name
...
>>> a = A("alpha")
>>> b = A("beta")
>>> a.method = new.instancemethod(method, a) # ...turned into a method...
>>> a.method()
alpha
>>> b.method() # ... but only known to a specific instance of A
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'A' object has no attribute 'method'

> builtins like dict or object. I remember at some point just doing
> something like:
> 
> x.fn = myfnFunction
> 
> and having it just work. 

With the caveat that x.fn is now an alias for myfnFunction, but doesn't get
x passed as its first argument (conventionally named 'self') and therefore
has no knowledge of the instance x.

> If I do that with an instance of generic 
> object however, I get an AttributeError. So:
> 
> x = object()
> x.fn = myFn
> 
> blows up. However, if I do
> 
> class nc(object):pass
> x = nc()
> x.fn = myFn
> 
> Then all is well.
> 
> checking for an ability on somebody is as simple as
> 
> 'fn' in dir(x)
> 
> or
> 
> hasattr(x, 'fn')
> 
> 
> I had thought this was a lot easier than I was making it out to be.
> What I don't know is why using an object derived from object allows
> you to dynamically add methods like this but the base object does not.
> At this point it is more of a curiosity than anything, but if somebody
> knows the answer off the top of their head, that would be great.

Arbitrary instance attributes are implemented via a dictionary (called
__dict__), and that incurs a certain overhead which is sometimes better to
avoid (think gazillion instances of some tiny class). For example, tuples
are derived from object but don't have a __dict__.
As a special case, what would happen if dict were to allow attributes? It
would need a __dict__ which would have a __dict__ which would have...
As a consequence object could no longer be the base class of all (newstyle)
classes.

Peter

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime and lambda

2007-05-04 Thread Mike
On May 4, 2:05 pm, Peter Otten <[EMAIL PROTECTED]> wrote:
> Mike wrote:
> > staticmethod makes the function available to the whole class according
> > to the docs. What if I only want it to be available on a particular
> > instance? Say I'm adding abilities to a character in a game and I want
> > to give a particular character the ability to 'NukeEverybody'. I don't
> > want all characters of that type to be able to wipe out the entire
> > planet, just the particular character that got the powerup.
>
> Static methods are for specialists, you don't need them. But then, your
> initial post looked like you were just exploring the possibilities...

Yeah, I'm just poking around.

>
> You can
>
> - have the Character.nuke_everybody() method check a self._can_nuke_eb flag

I don't like this one because it would require me to know every
ability everybody might ever have up front.

> - subclass the Character class with a NukingChar subclass and make only one
>   instance of that class

A possibility, I guess, but does this then mean I would need a new
class for every type of character? Probably not, but you would at
least need types grouped by general class, kind of like D&D characters
(Fighter, Magic User, etc.). It makes it harder for anybody to learn
anything they want.

> - add an instancemethod to one Character instance
>
> The simpler the approach you take the smarter you are ;)
>
> Peter

I just realized in working with this more that the issues I was having
with instancemethod and other things seems to be tied solely to
builtins like dict or object. I remember at some point just doing
something like:

x.fn = myfnFunction

and having it just work. If I do that with an instance of generic
object however, I get an AttributeError. So:

x = object()
x.fn = myFn

blows up. However, if I do

class nc(object):pass
x = nc()
x.fn = myFn

Then all is well.

checking for an ability on somebody is as simple as

'fn' in dir(x)

or

hasattr(x, 'fn')


I had thought this was a lot easier than I was making it out to be.
What I don't know is why using an object derived from object allows
you to dynamically add methods like this but the base object does not.
At this point it is more of a curiosity than anything, but if somebody
knows the answer off the top of their head, that would be great.

Thanks.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime and lambda

2007-05-04 Thread Peter Otten
Mike wrote:

> staticmethod makes the function available to the whole class according
> to the docs. What if I only want it to be available on a particular
> instance? Say I'm adding abilities to a character in a game and I want
> to give a particular character the ability to 'NukeEverybody'. I don't
> want all characters of that type to be able to wipe out the entire
> planet, just the particular character that got the powerup.

Static methods are for specialists, you don't need them. But then, your
initial post looked like you were just exploring the possibilities...

You can 

- have the Character.nuke_everybody() method check a self._can_nuke_eb flag
- subclass the Character class with a NukingChar subclass and make only one
  instance of that class
- add an instancemethod to one Character instance

The simpler the approach you take the smarter you are ;)

Peter
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime and lambda

2007-05-04 Thread Mike
On May 3, 11:25 pm, "Gabriel Genellina" <[EMAIL PROTECTED]>
wrote:
> En Thu, 03 May 2007 16:52:55 -0300, Mike <[EMAIL PROTECTED]> escribió:
>
> > I was messing around with adding methods to a class instance at
> > runtime and saw the usual code one finds online for this. All the
> > examples I saw say, of course, to make sure that for your method that
> > you have 'self' as the first parameter. I got to thinking and thought
> > "I have a lot of arbitrary methods in several utility files that I
> > might like to add to things. How would I do that?" And this is what I
> > came up with:
>
> I don't see the reason to do that. If you have a function that does not
> use its "self" argument, what do you get from making it an instance method?
> If -for whatever strange reason- you want it to actually be a method, use
> a static method:
>
> py> def foo(x):
> ...   print "I like %r" % x
> ...
> py> class A(object): pass
> ...
> py> a = A()
> py> A.foo = staticmethod(foo)
> py> a.foo()
> Traceback (most recent call last):
>File "", line 1, in 
> TypeError: foo() takes exactly 1 argument (0 given)
> py> a.foo("coffee")
> I like 'coffee'
> py> A.foo("tea")
> I like 'tea'
>
> --
> Gabriel Genellina

staticmethod makes the function available to the whole class according
to the docs. What if I only want it to be available on a particular
instance? Say I'm adding abilities to a character in a game and I want
to give a particular character the ability to 'NukeEverybody'. I don't
want all characters of that type to be able to wipe out the entire
planet, just the particular character that got the powerup.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime and lambda

2007-05-03 Thread Gabriel Genellina
En Thu, 03 May 2007 16:52:55 -0300, Mike <[EMAIL PROTECTED]> escribió:

> I was messing around with adding methods to a class instance at
> runtime and saw the usual code one finds online for this. All the
> examples I saw say, of course, to make sure that for your method that
> you have 'self' as the first parameter. I got to thinking and thought
> "I have a lot of arbitrary methods in several utility files that I
> might like to add to things. How would I do that?" And this is what I
> came up with:

I don't see the reason to do that. If you have a function that does not  
use its "self" argument, what do you get from making it an instance method?
If -for whatever strange reason- you want it to actually be a method, use  
a static method:

py> def foo(x):
...   print "I like %r" % x
...
py> class A(object): pass
...
py> a = A()
py> A.foo = staticmethod(foo)
py> a.foo()
Traceback (most recent call last):
   File "", line 1, in 
TypeError: foo() takes exactly 1 argument (0 given)
py> a.foo("coffee")
I like 'coffee'
py> A.foo("tea")
I like 'tea'

-- 
Gabriel Genellina
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime and lambda

2007-05-03 Thread ici
On May 3, 10:52 pm, Mike <[EMAIL PROTECTED]> wrote:
> I was messing around with adding methods to a class instance at
> runtime and saw the usual code one finds online for this. All the
> examples I saw say, of course, to make sure that for your method that
> you have 'self' as the first parameter. I got to thinking and thought
> "I have a lot of arbitrary methods in several utility files that I
> might like to add to things. How would I do that?" And this is what I
> came up with:
>
> def AddMethod(currObject, method, name = None):
> if name is None: name = method.func_name
> class newclass(currObject.__class__):pass
> setattr(newclass, name, method)
> return newclass()
>
> And lets say I have a utility function that can check if a drive
> exists on my windows box called HasDrive. I can add that like this:
>
> superdict = addm(dict(), lambda self, d: myUtils.HasDrive(d),
> "hasdrive")
>
> and then I can call
>
> superdict.HasDrive('c')
>
> lambda makes it possible to add any random function because you can
> use it to set self as the first parameter. I've found several real
> uses for this already. My big question is, will something like this be
> possible in python 3000 if lambda really does go away? I've not heard
> much about lambda, reduce, etc. lately but I know Guido wanted them
> out of the language.
>
> Is there a better way to do this today than to use lambda? It seemed
> the simplest way to do this that I could find.

from win32com.client import Dispatch as CreateObject

class HDDs(list):
def __init__(self):
fso = CreateObject('Scripting.FileSystemObject')
for d in fso.Drives:
if d.DriveType == 2: # Fixed
list.append(self, d.DriveLetter)

if __name__ == "__main__":
drv_list = HDDs()
for d in drv_list:
print d

try:
# Found
print drv_list.index('P')
except ValueError:
# Not Found
print "P: Not Exists!"

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime and lambda

2007-05-03 Thread James Stroud
Mike wrote:
> I was messing around with adding methods to a class instance at
> runtime and saw the usual code one finds online for this. All the
> examples I saw say, of course, to make sure that for your method that
> you have 'self' as the first parameter. I got to thinking and thought
> "I have a lot of arbitrary methods in several utility files that I
> might like to add to things. How would I do that?" And this is what I
> came up with:
> 
> 
> def AddMethod(currObject, method, name = None):
>   if name is None: name = method.func_name
>   class newclass(currObject.__class__):pass
>   setattr(newclass, name, method)
>   return newclass()
> 
> And lets say I have a utility function that can check if a drive
> exists on my windows box called HasDrive. I can add that like this:
> 
> superdict = addm(dict(), lambda self, d: myUtils.HasDrive(d),
> "hasdrive")
> 
> and then I can call
> 
> superdict.HasDrive('c')
> 
> lambda makes it possible to add any random function because you can
> use it to set self as the first parameter. I've found several real
> uses for this already. My big question is, will something like this be
> possible in python 3000 if lambda really does go away? I've not heard
> much about lambda, reduce, etc. lately but I know Guido wanted them
> out of the language.
> 
> Is there a better way to do this today than to use lambda? It seemed
> the simplest way to do this that I could find.
> 

You don't absolutely require lambda.

def add_self(afun):
   def _f(self, *args, **kwargs):
 return afun(*args, **kwargs)
   return _f

superdict = addm(dict(), add_self(myUtils.HasDrive), "hasdrive")

James
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: adding methods at runtime and lambda

2007-05-03 Thread Mike
In the above example 'addm' should be 'AddMethod'

superdict = AddMethod(dict(), lambda self, d:
myUtils.HasDrive(d),"hasdrive")

-- 
http://mail.python.org/mailman/listinfo/python-list


adding methods at runtime and lambda

2007-05-03 Thread Mike
I was messing around with adding methods to a class instance at
runtime and saw the usual code one finds online for this. All the
examples I saw say, of course, to make sure that for your method that
you have 'self' as the first parameter. I got to thinking and thought
"I have a lot of arbitrary methods in several utility files that I
might like to add to things. How would I do that?" And this is what I
came up with:


def AddMethod(currObject, method, name = None):
if name is None: name = method.func_name
class newclass(currObject.__class__):pass
setattr(newclass, name, method)
return newclass()

And lets say I have a utility function that can check if a drive
exists on my windows box called HasDrive. I can add that like this:

superdict = addm(dict(), lambda self, d: myUtils.HasDrive(d),
"hasdrive")

and then I can call

superdict.HasDrive('c')

lambda makes it possible to add any random function because you can
use it to set self as the first parameter. I've found several real
uses for this already. My big question is, will something like this be
possible in python 3000 if lambda really does go away? I've not heard
much about lambda, reduce, etc. lately but I know Guido wanted them
out of the language.

Is there a better way to do this today than to use lambda? It seemed
the simplest way to do this that I could find.

-- 
http://mail.python.org/mailman/listinfo/python-list