Dynamically add method to instance

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
ttmetro
Posts: 104
Joined: Mon Jul 31, 2017 12:44 am

Dynamically add method to instance

Post by ttmetro » Sun Mar 03, 2019 1:09 am

How do I add a function dynamically to a MicroPython object?

In standard python "MethodType" is used for this, but it seems missing from MicroPython. Is there a workaround?

Thanks,
Bernhard
Bernhard Boser

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Dynamically add method to instance

Post by jickster » Sun Mar 03, 2019 1:16 am

Obj.thing = function

?


Sent from my iPhone using Tapatalk Pro

ttmetro
Posts: 104
Joined: Mon Jul 31, 2017 12:44 am

Re: Dynamically add method to instance

Post by ttmetro » Sun Mar 03, 2019 7:57 pm

I don't think that binds it to the instance. Hence no reference to "self".

I used a global as a workaround. Not pretty, but works.
Bernhard Boser

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: Dynamically add method to instance

Post by jickster » Sun Mar 03, 2019 11:13 pm

ttmetro wrote:I don't think that binds it to the instance. Hence no reference to "self".

I used a global as a workaround. Not pretty, but works.
Have you actually tried it?



Sent from my iPhone using Tapatalk Pro

ttmetro
Posts: 104
Joined: Mon Jul 31, 2017 12:44 am

Re: Dynamically add method to instance

Post by ttmetro » Mon Mar 04, 2019 2:54 am

yes!

Also what I found with a web search is that this is exactly what

Code: Select all

MethodType
is for.
Bernhard Boser

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Dynamically add method to instance

Post by stijn » Mon Mar 04, 2019 8:37 am

Not 100% sure what you mean, can you give an example maybe?

Possibly you mean something like

Code: Select all

class Foo:
  pass

def Stuff(obj):
  print('Stuff', obj)

f = Foo()
print(f)
f.stuff = lambda: Stuff(f)
f.stuff()
?

User avatar
mattyt
Posts: 410
Joined: Mon Jan 23, 2017 6:39 am

Re: Dynamically add method to instance

Post by mattyt » Mon Mar 04, 2019 11:04 am

I believe Bernhard is talking about adding a member function to an instance of a class. MethodType is the standard way to do this. It appears to be implemented in the micropython-lib types module.

ttmetro
Posts: 104
Joined: Mon Jul 31, 2017 12:44 am

Re: Dynamically add method to instance

Post by ttmetro » Tue Mar 05, 2019 12:32 am

Yes, that's what I want:

Code: Select all

from types import MethodType

class DynamicTest:

    def __init__(self):
        self.x = 5

    def a(self):
        return self.x

dt = DynamicTest()

def b(self):
    return self.x

dt.b = b

def c(self):
    return self.x

setattr(dt, 'c', MethodType(c, dt))

print('a', dt.a())
# print('b', dt.b())
print('c', dt.c())
Result:
  • a works as expected.
  • b fails: TypeError: function takes 1 positional arguments but 0 were given (also expected)
  • c fails: TypeError: cannot create 'bound_method' instances
a and c work with cpython, b fails (as it should).

So seems like a feature that is missing from MicroPython. Fortunately there is a workaround, at least for my case.

Thanks for all the suggestions!
Bernhard Boser

Post Reply