Chickenmarkus
Chickenmarkus

Reputation: 1161

Call class method with different class

Let's assume we have the following two classes:

class Class1:
    def method(self):
        print("Class1.method() with self =", self)
    @classmethod
    def clsmethod(cls):
        print("Class1.clsmethod() with cls =", cls)
obj1 = Class1()

class Class2:
    def method(self):
        print("Class2.method() with self =", self)
    @classmethod
    def clsmethod(cls):
        print("Class2.clsmethod() with cls =", cls)
obj2 = Class2()

For normal bound methods, it is easy to inject a different self. We just have to call Class1's method() but with obj2 as self:

>>> Class1.method(o2)
Class1.method() with self = <__main__.Class2 object at 0x...>

The question is now: How can I do similar things but with classmethods?

>>> Class1.clsmethod(Class2)
Class1.clsmethod() with cls = <__main__.Class2 object at 0x...>

By what does Class1 have to be replaced? The intuitive approach of using type(Class1) ("the class of Class1" similar to "the class of obj1) does not work because a class method is not a attribute of the metaclass.

Upvotes: 4

Views: 277

Answers (1)

falsetru
falsetru

Reputation: 368894

By accessing __func__ attribute, you can get unbound function object.

class Class1:
    def method(self):
        print("Class1.method() with self =", self)
    @classmethod
    def clsmethod(cls):
        print("Class1.clsmethod() with cls =", cls)

class Class2:
    def method(self):
        print("Class2.method() with self =", self)
    @classmethod
    def clsmethod(cls):
        print("Class2.clsmethod() with cls =", cls)

Class1.clsmethod.__func__(Class2)  # <----
# prints
# Class1.clsmethod() with cls = <class '__main__.Class2'>

Class2.clsmethod.__func__(Class1)  # <----
# prints
# Class2.clsmethod() with cls = <class '__main__.Class1'>

Upvotes: 3

Related Questions