Why am I Able to Call the Class Method as If It Were an Instance Method Here

Python - why can I call a class method with an instance?

You can call it on an instance because @classmethod is a decorator (it takes a function as an argument and returns a new function).

Here is some relavent information from the Python documentation

It can be called either on the class (such as C.f()) or on an instance
(such as C().f()). The instance is ignored except for its class. If a
class method is called for a derived class, the derived class object
is passed as the implied first argument.

There's also quite a good SO discussion on @classmethod here.

Call instance method in class method in Python

It's because of how you're calling second.

Say you have such a class:

class A:

def do_thing(self):
pass

The following are equivalent:

a = A()
a.do_thing()

A.do_thing(a)

In other words, when we call a method of an instance, it is the same as looking up a function attribute of the class object and calling it with that instance as the first argument.

Now, note that when you call second, you pass cls to it. That is the class object and not an instance, which means that you're doing something like A.do_thing. Therefore, for it to know which instance you want to call third on, you need to pass in self.

ELI5: Why can you call class methods within class methods without explicitly stating the class itself? (Ruby/Rails)

Whenever you call a method, Ruby first checks to see if it's defined on self. There is only one exception to this that I know of - if you have a local variable with the same name as the method, it will reference the local variable instead:

def num; 1; end
num = 2
num # => 2

Class methods are the same as instance methods in this regard.

It's easier to think of the cases where you can't omit the self:

  • When using a setter method e.g. self.foo = "bar" it's required because Ruby needs to know you're not trying to just set a local variable (as foo = "bar" would):

    class Test
    attr_writer :foo
    def initialize
    self.foo = 1 # calls the setter method
    foo = 2 # creates a local variable
    end
    end
  • When there's ambiguity between a local variable and a method (both have the same name) and you want to call the method:

    class Foo
    def self.a; 1; end
    def self.b
    a = 2
    a # references local variable
    self.a # calls method
    a() # can also call the method by writing out parens (removes ambiguity)
    end
    end
  • When self is not what you want it to be in that scope.

    class Foo
    def self; a; 1
    end

    a # obviously doesn't work, it isn't defined here
    Foo.a # works
  • When the method name is the same as a reserved word (e.g. class)

    def class_name
    class.name # syntax error, it thinks you want to define a class
    self.class.name # works
    end

Calling instance method from class method, allowed in python3, disallowed in python 2?

In Python 3 methods are regular function objects (not "unbound method" instances) and therefore they do not check that the first argument is an instance of the class.

Not sure why this change was considered important (uniformity or performance, probably) but what you observed looks like an unwanted side effect of this choice.

How to define one method as both instance method and class method (sharing the same name), each with different arguments?

You can let self take a default argument as well, so that you can distinguish between mine.bar() and MyClass.bar(). The price is that the other two arguments must be keyword arguments.

class MyClass:

_sentinel = object()

def bar(self=None, *, arg1=_sentinel, arg2=_sentinel):
if self is not None:
if arg1 is _sentinel:
arg1 = self.arg1
if arg2 is _sentinel:
arg2 = self.arg2
else:
if arg1 is _sentinel:
raise ValueError("Missing required arg1")
if arg2 is _sentinel:
raise ValueError("Missing required arg2")

return foo(arg1, arg2)

mine.bar() # self is mine, arg1 is _sentinel, arg2 is _sentinel

MyClass.bar(arg1=3, arg2=4)

How to call instance method from within class method?

If you want to send an instance method, then you need an instance. There's no way around that.

If your class method wants to call an instance method, then it is quite possible that either the instance method should be a class method, or the class method should be an instance method. So have a look at that and maybe change your design.

Otherwise, your class method must create an instance, or get an instance from somewhere, and send the instance method to the instance.

instance methods from class methods swift

What you are trying to do rarely makes any sense from a design perspective.

By definition, an instance method operates on an instance of an object.
For example, it might require access to some instance members, or somehow meddle with the state of the object you call the method on.

class methods on the other hand do not require an instance to be able to call them - and should in general only operate on the given parameters, not be dependant on shared state.

If you need to call instanceMethod() in classMethod(), and instanceMethod() does not require any state - why is it not also a class method, or a (global) pure function?



Related Topics



Leave a reply



Submit