1

Consider this example:

class master:
    @classmethod 
    def foo(cls):
        cls.bar()

class slaveClass( master ):
    @classmethod 
    def bar(cls):
        print("This is class method")

slaveType = slaveClass
slaveType.foo()

class slaveInstance( master ):
    #def foo(self):
    #    self.foo()
    def __init__(self,data):
        self.data=data
        print("Instance has been made")
    def bar(self):
        print("This is "+self.data+" method")


slaveType = slaveInstance("instance")
slaveType.foo()

I know it works when last definition of foo is uncommented, but is there any other way to use this foo function without changing the usage. I have large project where classes defined the way things worked and I was able to change the way with slaveType but there happen to be a case where instance is needed, and there is bit too many foo like functions to be overridden for instance behavior.

Thank you stackers!

Johu
  • 626
  • 7
  • 15
  • How could that work? The original `foo` is a classmethod, so simply never receives the instance - only the class. There's no way it could then call an instance method. – Daniel Roseman Sep 09 '11 at 13:21
  • I edited the example a little, so it is bit more clear, what I need to do. If I uncommented the last `foo` definition I will never call the classmethod, as it is overridden by instance method. I want to know, if there is any other way. I am able to change the master class but I need to keep the way `slaveType` was used. – Johu Sep 09 '11 at 13:28
  • I have to recommend biting the bullet and getting rid of the classmethods altogether. Anything else will produce complicated code which you'll regret down the road. – Winston Ewert Sep 10 '11 at 14:19
  • Trying to decode this question into something Pythonic. `slaveClass` is a child class that inherits classmethod `foo()` from Master. `slaveInstance` is a grandchild class (not an instance) that then overrides `foo()` as an instance method. (Btw, style points to avoid confusion: class names should be CamelCase, and never include 'Class' (this ain't Java) or `Instance` or `Type` (just plain wrong, in a class name). So: `slaveClass` should simply be `Slave`, and 'master` be `Master`. `slaveType` is not a type, it's an instance... – smci Dec 15 '20 at 05:15
  • By "I want to know, if there is any other way." I think you meant *"Can I subclass and override a classmethod as an instance method, but still also be able to call it as classmethod from the grandchild class?"* – smci Dec 15 '20 at 05:16

1 Answers1

0

Look closer at the doc for classmethod. Instance methods pass an instance as the first argument, and class methods pass a class as the first argument. Calling slaveType.foo() passes an instance, slaveType, as the first argument of foo(). foo() is expecting a class as the first argument.

krs1
  • 1,125
  • 7
  • 16
  • I know it. I was trying to come up with a way to bypass this as cls.bar() would work also if cls was actually an instance not a type. – Johu Sep 10 '11 at 13:25