What is an "instance method"?
Question:
From 3. Data model:
Instance methods
An instance method object combines a class, a class instance and any
callable object (normally a user-defined function).
If it is a definition, what does it mean?
If it is not a definition, what is the definition of an "instance method"?
Is an "instance method" the same concept of a method of a class?
Since someone brings up class methods and static methods, bound methods and unbound methods, let me clarify:
I understand a method of a class can be an ordinary method, a class method, or a static method. I understand a method of a class accessed via the class or its instance can be bound or function. I have never heard of "an instance method". I don’t know what it is even after looking at the quote and am not sure if it is related to a ordinary method, a class method, or a static method, or a bound method or function.
Answers:
>>> class Foo:
... def im_a_method(self):
... pass
...
>>> x = Foo()
>>> x.im_a_method
<bound method Foo.im_a_method of <__main__.Foo object at 0x7f4f1993dd30>>
Tada! That’s an instance method object. It’s the thing you get when you retrieve a method of an object, before you call it.
What is an instance method?
An instance method is a function the is bound to a class instance. The instance of the class is implicitly passed as the first argument to instance methods. It essentially belongs to that specific instance. An instance method is the “normal” type of method people use. This is opposed to a static method or class method created using staticmethod
and classmethod
respectively.
Here’s an example of an instance method:
>>> class Class:
... def method(self):
... pass
>>> Class.method
<bound method Class.method of <Class object at 0x7f12781c5b70>>
It’s that simple.
Your confusion comes from what exactly this definition is about. The term “instance method” is actually used to describe both the concept (a method that works on an instance – by opposition with a classmethod or staticmethod) and its technical implementation. The definition you quote is about the technical implementation.
If you want to understand the context of this definition, you can read this article in the Python wiki, which explains how Python turns functions into methods at runtime.
An instance method:
-
can call instance and class variables and instance, class and static methods by self
.
-
can call class variables and instance, class and static methods by class name but not instance variables.
-
can be called by object.
-
can be also called directly by class name but when called directly by class name, we need to pass one argument to the instance method because self
becomes the normal parameter which doesn’t have the ability to call instance and class variables and instance, class and static methods.
-
needs self
for the 1st argument otherwise the instance method cannot be called by an object but the instance method can still be called directly by class name and the name of self
is used in convention so other names instead of self
still work.
*I also explain about @classmethod and @staticmethod in my answer for @classmethod vs @staticmethod in Python.
For example, the instance method can call the instance and class variables and the instance, class and static methods by self
and the instance method can call the class variable and the instance, class and static methods by class name but not the instance variables and the instance method can be called by object as shown below:
class Person:
x = "Hello"
def __init__(self, name):
self.name = name
def test1(self): # Instance method
print(self.name) # Instance variable by "self"
print(self.x) # Class variable by "self"
self.test2() # Instance method by "self"
self.test3() # Class method by "self"
self.test4() # Static method by "self"
print()
print(Person.x) # Class variable by class name
Person.test2("Test2") # Instance method by class name
Person.test3() # Class method by class name
Person.test4() # Static method by class name
def test2(self):
print("Test2")
@classmethod
def test3(cls):
print("Test3")
@staticmethod
def test4():
print("Test4")
obj = Person("John")
obj.test1() # By object
Output:
John # Instance variable by "self"
Hello # Class variable by "self"
Test2 # Instance method by "self"
Test3 # Class method by "self"
Test4 # Static method by "self"
Hello # Class variable by class name
Test2 # Instance method by class name
Test3 # Class method by class name
Test4 # Static method by class name
And, if the instance method tries to call the instance variable by class name as shown below:
# ...
def test1(self): # Instance method
print(Person.name) # Instance variable by class name
obj = Person("John")
obj.test1()
The error below occurs:
AttributeError: type object ‘Person’ has no attribute ‘name’
And, the instance method can be also called directly by class name but when called directly by class name, we need to pass one argument to the instance method as shown below because self
becomes the normal parameter which doesn’t have the ability to call the instance and class variables and the instance, class and static methods by self
:
# ...
def test1(self): # Instance method
print(self)
# ...
Person.test1("Test1") # Here
Output:
Test1
So, if the instance method tries to call the instance and class variables and the instance, class and static methods by self
as shown below:
# ...
def test1(self): # Instance method
print(self.name) # Instance variable or
print(self.x) # Class variable or
self.test2() # Instance method or
self.test3() # Class method or
self.test4() # Static method
# ...
Person.test1("Test1") # Here
The errors below occur because again, self
becomes the normal parameter which doesn’t have the ability to call the instance and class variables and the instance, class and static methods:
AttributeError: ‘str’ object has no attribute ‘name’
AttributeError: ‘str’ object has no attribute ‘x’
AttributeError: ‘str’ object has no attribute ‘test2’
AttributeError: ‘str’ object has no attribute ‘test3’
AttributeError: ‘str’ object has no attribute ‘test4’
And, if one argument is not passed to the instance method as shown below:
# ...
def test1(self): # Instance method
print(self)
# ...
Person.test1() # Here
The error below occurs:
TypeError: test1() missing 1 required positional argument: ‘self’
And, the instance method needs self
for the 1st argument otherwise the instance method cannot be called by object as shown below:
# ...
def test1(): # Without "self"
print("Test1")
# ...
obj = Person("John")
obj.test1() # Here
Then, the error below occurs:
TypeError: test1() takes 0 positional arguments but 1 was given
But, the instance method without self
can still be called directly by class name as shown below:
# ...
def test1(): # Without "self"
print("Test1")
# ...
Person.test1() # Here
Output:
Test1
And, the name of self
is used in convention in an instance method so other name instead of self
still works as shown below:
# ...
# Here
def test1(orange): # Instance method
print(orange.name) # Instance variable
print(orange.x) # Class variable
orange.test2() # Instance method
orange.test3() # Class method
orange.test4() # Static method
# ...
obj = Person("John")
obj.test1()
Output:
John
Hello
Test2
Test3
Test4
From 3. Data model:
Instance methods
An instance method object combines a class, a class instance and any
callable object (normally a user-defined function).
If it is a definition, what does it mean?
If it is not a definition, what is the definition of an "instance method"?
Is an "instance method" the same concept of a method of a class?
Since someone brings up class methods and static methods, bound methods and unbound methods, let me clarify:
I understand a method of a class can be an ordinary method, a class method, or a static method. I understand a method of a class accessed via the class or its instance can be bound or function. I have never heard of "an instance method". I don’t know what it is even after looking at the quote and am not sure if it is related to a ordinary method, a class method, or a static method, or a bound method or function.
>>> class Foo:
... def im_a_method(self):
... pass
...
>>> x = Foo()
>>> x.im_a_method
<bound method Foo.im_a_method of <__main__.Foo object at 0x7f4f1993dd30>>
Tada! That’s an instance method object. It’s the thing you get when you retrieve a method of an object, before you call it.
What is an instance method?
An instance method is a function the is bound to a class instance. The instance of the class is implicitly passed as the first argument to instance methods. It essentially belongs to that specific instance. An instance method is the “normal” type of method people use. This is opposed to a static method or class method created using staticmethod
and classmethod
respectively.
Here’s an example of an instance method:
>>> class Class:
... def method(self):
... pass
>>> Class.method
<bound method Class.method of <Class object at 0x7f12781c5b70>>
It’s that simple.
Your confusion comes from what exactly this definition is about. The term “instance method” is actually used to describe both the concept (a method that works on an instance – by opposition with a classmethod or staticmethod) and its technical implementation. The definition you quote is about the technical implementation.
If you want to understand the context of this definition, you can read this article in the Python wiki, which explains how Python turns functions into methods at runtime.
An instance method:
-
can call instance and class variables and instance, class and static methods by
self
. -
can call class variables and instance, class and static methods by class name but not instance variables.
-
can be called by object.
-
can be also called directly by class name but when called directly by class name, we need to pass one argument to the instance method because
self
becomes the normal parameter which doesn’t have the ability to call instance and class variables and instance, class and static methods. -
needs
self
for the 1st argument otherwise the instance method cannot be called by an object but the instance method can still be called directly by class name and the name ofself
is used in convention so other names instead ofself
still work.
*I also explain about @classmethod and @staticmethod in my answer for @classmethod vs @staticmethod in Python.
For example, the instance method can call the instance and class variables and the instance, class and static methods by self
and the instance method can call the class variable and the instance, class and static methods by class name but not the instance variables and the instance method can be called by object as shown below:
class Person:
x = "Hello"
def __init__(self, name):
self.name = name
def test1(self): # Instance method
print(self.name) # Instance variable by "self"
print(self.x) # Class variable by "self"
self.test2() # Instance method by "self"
self.test3() # Class method by "self"
self.test4() # Static method by "self"
print()
print(Person.x) # Class variable by class name
Person.test2("Test2") # Instance method by class name
Person.test3() # Class method by class name
Person.test4() # Static method by class name
def test2(self):
print("Test2")
@classmethod
def test3(cls):
print("Test3")
@staticmethod
def test4():
print("Test4")
obj = Person("John")
obj.test1() # By object
Output:
John # Instance variable by "self"
Hello # Class variable by "self"
Test2 # Instance method by "self"
Test3 # Class method by "self"
Test4 # Static method by "self"
Hello # Class variable by class name
Test2 # Instance method by class name
Test3 # Class method by class name
Test4 # Static method by class name
And, if the instance method tries to call the instance variable by class name as shown below:
# ...
def test1(self): # Instance method
print(Person.name) # Instance variable by class name
obj = Person("John")
obj.test1()
The error below occurs:
AttributeError: type object ‘Person’ has no attribute ‘name’
And, the instance method can be also called directly by class name but when called directly by class name, we need to pass one argument to the instance method as shown below because self
becomes the normal parameter which doesn’t have the ability to call the instance and class variables and the instance, class and static methods by self
:
# ...
def test1(self): # Instance method
print(self)
# ...
Person.test1("Test1") # Here
Output:
Test1
So, if the instance method tries to call the instance and class variables and the instance, class and static methods by self
as shown below:
# ...
def test1(self): # Instance method
print(self.name) # Instance variable or
print(self.x) # Class variable or
self.test2() # Instance method or
self.test3() # Class method or
self.test4() # Static method
# ...
Person.test1("Test1") # Here
The errors below occur because again, self
becomes the normal parameter which doesn’t have the ability to call the instance and class variables and the instance, class and static methods:
AttributeError: ‘str’ object has no attribute ‘name’
AttributeError: ‘str’ object has no attribute ‘x’
AttributeError: ‘str’ object has no attribute ‘test2’
AttributeError: ‘str’ object has no attribute ‘test3’
AttributeError: ‘str’ object has no attribute ‘test4’
And, if one argument is not passed to the instance method as shown below:
# ...
def test1(self): # Instance method
print(self)
# ...
Person.test1() # Here
The error below occurs:
TypeError: test1() missing 1 required positional argument: ‘self’
And, the instance method needs self
for the 1st argument otherwise the instance method cannot be called by object as shown below:
# ...
def test1(): # Without "self"
print("Test1")
# ...
obj = Person("John")
obj.test1() # Here
Then, the error below occurs:
TypeError: test1() takes 0 positional arguments but 1 was given
But, the instance method without self
can still be called directly by class name as shown below:
# ...
def test1(): # Without "self"
print("Test1")
# ...
Person.test1() # Here
Output:
Test1
And, the name of self
is used in convention in an instance method so other name instead of self
still works as shown below:
# ...
# Here
def test1(orange): # Instance method
print(orange.name) # Instance variable
print(orange.x) # Class variable
orange.test2() # Instance method
orange.test3() # Class method
orange.test4() # Static method
# ...
obj = Person("John")
obj.test1()
Output:
John
Hello
Test2
Test3
Test4