binding instance method of one class to another class

136 Views Asked by At

Consider the following case:

class test:
  def foo(self, o):
    print(o)

  @staticmethod
  def bar(o):
    print(o)
    
  @classmethod
  def qux(cls, o):
    print(cls)
    print(o)

def baz(o):
  print(o)

t = test()

class A:
  meth1 = t.bar
  meth2 = t.foo
  meth3 = baz
  meth4 = t.qux

a = A()
a.meth1()
a.meth3()
# a.meth4()
# a.meth2()

This works just fine, but if I call meth2/4 I get the following error:

TypeError: <foo/qux>() missing 1 required positional argument: 'o'

Is there any way I can get t.foo and t.qux working like t.bar and baz?

1

There are 1 best solutions below

7
On

meth4 in A isn't being treated as a class method here because you have not defined it as such.

Class methods are declared using decorator syntax, like so:

@decorator
def func(x, y):
    return z

which essentially defines a function func and then calls decorator on it.

Thus, you can actually just do meth4 = classmethod(t.qux), and it works perfectly fine.

For meth2, I'm not sure what you expected to happen. It's an instance method that takes self implicitly and takes an argument o, so when you call a.meth2, of course you need to specify an argument o.