473,396 Members | 1,933 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

adding methods at runtime and lambda

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.

May 3 '07 #1
9 1361
In the above example 'addm' should be 'AddMethod'

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

May 3 '07 #2
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
May 3 '07 #3
ici
On May 3, 10:52 pm, Mike <msu...@comcast.netwrote:
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!"

May 3 '07 #4
En Thu, 03 May 2007 16:52:55 -0300, Mike <ms****@comcast.netescribió:
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:

pydef foo(x):
.... print "I like %r" % x
....
pyclass A(object): pass
....
pya = A()
pyA.foo = staticmethod(foo)
pya.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 1 argument (0 given)
pya.foo("coffee")
I like 'coffee'
pyA.foo("tea")
I like 'tea'

--
Gabriel Genellina
May 4 '07 #5
On May 3, 11:25 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
En Thu, 03 May 2007 16:52:55 -0300, Mike <msu...@comcast.netescribió:
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:

pydef foo(x):
... print "I like %r" % x
...
pyclass A(object): pass
...
pya = A()
pyA.foo = staticmethod(foo)
pya.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 1 argument (0 given)
pya.foo("coffee")
I like 'coffee'
pyA.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.

May 4 '07 #6
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
May 4 '07 #7
On May 4, 2:05 pm, Peter Otten <__pete...@web.dewrote:
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.

May 4 '07 #8
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 "<stdin>", line 1, in <module>
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

May 4 '07 #9
On May 4, 5:46 pm, Peter Otten <__pete...@web.dewrote:
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 "<stdin>", line 1, in <module>
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.

May 7 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Fernando Rodriguez | last post by:
Hi, How can I add new methods at runtime to a class?
99
by: David MacQuigg | last post by:
I'm not getting any feedback on the most important benefit in my proposed "Ideas for Python 3" thread - the unification of methods and functions. Perhaps it was buried among too many other less...
4
by: C GIllespie | last post by:
Dear All, I have a class the looks something like this: class file: def __init__(self): pass def file2ps(self): return 'ps'
4
by: Max Derkachev | last post by:
Good day to all. Some time ago I'd been playing with a framework which uses dynamic class creation havily. Say, I could do: class A: pass # I method name is dynamic meth_name = 'foo'
2
by: manohar.shankar | last post by:
Hi, I have been searching on this topic for quite sometime and didnt get any answer. Is there a way I can extend/add methods/properties to a C# class during runtime. eg., I have class:...
5
by: Joseph Barillari | last post by:
Hi python-list, I've just started using new-style classes and am a bit confused as to why I can't seem to alter methods with special names (__call__, etc.) of new-style class instances. In other...
3
by: raylopez99 | last post by:
The headline says it all. Great minds think alike: read the blog below from three years ago, as endorsed by Ritchie, who coinvented C. BTW the below lambda expression code will not work (.Where...
0
by: Steven Samuel Cole | last post by:
Hello, I am writing an application that controls robots. Different robots can do different kinds of movements, such as e.g. open gripper, rotate gripper, etc. My RobotControl class should...
2
by: Maric Michaud | last post by:
Le Monday 25 August 2008 11:37:23 Steven Samuel Cole, vous avez écrit : i don't get your design, it seems over-complicated to mee at first glance. ... The free variable movementType in the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.