1

I have a function that I can't modify as it's a 3rd party, lets say it's an add function.

def add(a, b):
    print(a + b)

For this example lets call it in init. It has to be assigned to the class as a class variable. That way it will automatically become a bounded method. In order to prevent "bounding" I need to decorate it with a staticmethod.

class Base:
    func: Callable

    def __init__(self):
        self.func(a=1, b=2)


class Working(Base):
    func = staticmethod(add)

And it is working fine as that way self is not passed to the function.

I was wondering if it's possible to "unbound" / make it static in init

class NotWorking(Base):
    func = add

    def __init__(self):
        staticmethod(self.func)(a=1, b=2)

It has to be reusable from the Base class so I don't need to rewrite the same thing over and over.

class NotWorking2(Base):
    func = subtract

It's not something I need, I was just wondering if it's possible to "unbound" it once it was bounded.

In Working class it's just a function

<function add at 0x7f1be89de1f0>

but in NotWorking it's either

<bound method add of <__main__.NotWorking object at 0x7f0ed11e47f0>>

or a staticmethod which results in

TypeError: 'staticmethod' object is not callable

I have seen 'staticmethod' object is not callable but it doesn't really answer my question.

I don't think it's possible but is there a cleaner way so the staticmethod can be called only once if I have plenty of such classes?

Tom Wojcik
  • 5,471
  • 4
  • 32
  • 44

1 Answers1

3

The simplest way is to simply not call it as a method on self:

class Base:
    func: typing.ClassVar[Callable]

    def __init__(self):
        type(self).func(a=1, b=2)

class NowWorking(Base):
    func = add

Original answer:

class NowWorking(Base):
    func = add

    def __init__(self):
        NowWorking.func(a=1, b=2)
Jasmijn
  • 9,370
  • 2
  • 29
  • 43
  • The problem is I have a lot of classes like that and the idea is not to do anything in `init` but rather add it in the interface / abstractclass - here, `Base`. – Tom Wojcik Mar 12 '21 at 13:55
  • 1
    You could also call `type(self).func`, which is more flexible I suppose. – Jasmijn Mar 12 '21 at 13:57
  • 1
    By the way, I think the type of `Base.func` should be `typing.ClassVar[Callable]`. – Jasmijn Mar 12 '21 at 13:58
  • `func = type(self).func` did the trick. Thank you! And you're right on the type. Will accept in 3 min. – Tom Wojcik Mar 12 '21 at 14:00
  • Glad to hear it! I didn't make that my initial answer because I thought there was an edge-case w/ subclassing but I tried it out and it worked just fine. – Jasmijn Mar 12 '21 at 14:06