Calling a base class's classmethod in Python

后端 未结 4 1852
独厮守ぢ
独厮守ぢ 2020-12-12 23:20

Consider the following code:

class Base(object):

    @classmethod
    def do(cls, a):
        print cls, a

class Derived(Base):

    @classmethod
    def d         


        
相关标签:
4条回答
  • 2020-12-12 23:42

    This works for me:

    Base.do('hi')
    
    0 讨论(0)
  • 2020-12-12 23:43

    If you're using a new-style class (i.e. derives from object in Python 2, or always in Python 3), you can do it with super() like this:

    super(Derived, cls).do(a)
    

    This is how you would invoke the code in the base class's version of the method (i.e. print cls, a), from the derived class, with cls being set to the derived class.

    0 讨论(0)
  • 2020-12-12 23:45

    Building on the answer from @David Z using:

    super(Derived, cls).do(a)
    

    Which can be further simplified to:

    super(cls, cls).do(a)
    

    I often use classmethods to provide alternative ways to construct my objects. In the example below I use the super functions as above for the class method load that alters the way that the objects are created:

    class Base():
        
        def __init__(self,a):
            self.a = a
        
        @classmethod
        def load(cls,a):
            return cls(a=a)
        
    class SubBase(Base): 
    
        @classmethod
        def load(cls,b):
            a = b-1
            return super(cls,cls).load(a=a)
        
    base = Base.load(a=1)
    print(base)
    print(base.a)
    
    sub = SubBase.load(b=3)
    print(sub)
    print(sub.a)
    

    Output:

    <__main__.Base object at 0x128E48B0>
    1
    <__main__.SubBase object at 0x128E4710>
    2
    
    0 讨论(0)
  • 2020-12-12 23:56

    this has been a while, but I think I may have found an answer. When you decorate a method to become a classmethod the original unbound method is stored in a property named 'im_func':

    class Base(object):
        @classmethod
        def do(cls, a):
            print cls, a
    
    class Derived(Base):
    
        @classmethod
        def do(cls, a):
            print 'In derived!'
            # Base.do(cls, a) -- can't pass `cls`
            Base.do.im_func(cls, a)
    
    if __name__ == '__main__':
        d = Derived()
        d.do('hello')
    
    0 讨论(0)
提交回复
热议问题