Search code examples
pythonpython-3.xmetaclassclass-method

Why Python's inline classmethods behave differently to metaclass defined methods


A classmethod, whether defined inline or as part of the metaclass can always be called on the type:

class eggs( type ):
    def f1( cls ):
        print( "eggs" )


class spam( metaclass = eggs ):
    @classmethod
    def f2( cls ):
        print( "spam" )


f = spam()
type(f).f2() #--> spam
type(f).f1() #--> eggs

However, it seems a classmethod defined in a meta-class cannot be called on an instance:

f.f2() #--> spam
f.f1() #--> AttributeError

Why is this?


Solution

  • Classes are instances of their metaclass; you can call the metaclass defined methods on the class itself (because it's an instance of the metaclass), but they're not available to instances of the class (because they're not instances of the metaclass).

    This is intentional; there are use cases for providing behaviors to the class itself that can't be confused with features of the class's instances, and this is it.