Reputation: 1161
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
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