0

I'm trying to make a class static method, and then use it in a class variable as a callback. I'm running into a problem with the static method not being callable that I can't figure out:

from dataclasses import dataclass
from typing import Callable

@dataclass
class Option:
    txt: str
    callback: Callable

class Window:

    @staticmethod
    def _doit(a=1):
        print('do it with a', a)

    cvar = Option(txt='doit', callback=_doit)


w1 = Window()

w1._doit()
# works fine
Window._doit()
# works fine
w1.cvar.callback()
# this fails

The last call above fails with "TypeError: 'staticmethod' object is not callable".

I'm not sure why here, but even more confusing to me is if I remove the @staticmethod line, then things work 'correctly' - with all 3 calls in the code working.

I know I must being doing something stupid wrong, but I can't figure out what's wrong with the above ...any help?

thanks!

Richard
  • 3,024
  • 2
  • 17
  • 40

2 Answers2

1

EDIT: Oops, @Richard correctly pointed out that my original example was broken - I did not see the error since I had already defined the Window class running the original code. A bit tricky, but here is a version that should work along with a more detailed explanation.

EDIT #2: Sigh, fixed another typo. :^(

Example:

cvar = Option(txt='doit', callback=_doit.__func__)
rhurwitz
  • 2,557
  • 2
  • 10
  • 18
  • Thanks - that was my first thought, which I tried. ...but that fails, with `name 'Window' is not defined`. – Richard Feb 18 '21 at 20:02
  • ...thanks! ...note you need to edit your answer to remove the () after __func__ ...otherwise it will execute the function, not point to the function. – Richard Feb 18 '21 at 22:30
0

Thanks to the comment above, I checked this previous answer to similar question.

To correct the code above - where you're trying to reference a static method before it's bound - you need to reference the function location directly:

class Window:

    @staticmethod
    def _doit(a=1):
        print('do it with a', a)

    cvar = Option(txt='doit', callback=_doit.__func__)

The other option (which I'd already found worked, but preferred to identify my function explicitly as a staticmethod, was to remove the staticmethod decorator.

Richard
  • 3,024
  • 2
  • 17
  • 40