2

Passing a class, or a totally different object, as the first argument to method is easy:

class Foo:
   def method(self): ...

Foo.method(object())  # pass anything to self

I wonder, is this possible with classmethods as well? I assume it is, but how can it be done?

class Foo:
   @classmethod
   def cls_method(cls): ...

Foo.cls_method  # how to pass cls=object

Related: hybrid / class_or_instance_method decorator / descriptor, but that is not a setting I am interested in.

1
  • Why would you want to do this? Commented Jun 15 at 12:45

1 Answer 1

1

On a very high level you could see the classmethod as a partial method that binds the first argument.

To be more precise when a function attribute, i.e. a method, is accessed its __get__ method kicks in. For normal methods it transforms obj.f(*args) to f(obj, *args). If called from a class there is no extra argument injected. For classmethod it is a bit different as there is always a type injected: If called from an object: f(type(obj), *args), or if called from a class f(cls, *args) [1].

If you want to circumvent this you need to bypass the classmethod and access the function directly, you can do this via the __func__ attribute:

print(type(Foo.cls_method))  # method
print(type(Foo.cls_method.__func__))  # function
Foo.cls_method.__func__(object()) # no transformation, pass what you want
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.