Re: adding methods at runtime
[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
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
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
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
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
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
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
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
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
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
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
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
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
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