Reputation: 139
I am learning OOP in python and following this and this stackoverflow answers and this post
I understood how class works and how method called and all things but i have some doubts:
Consider this fragment of code:
class Point(object):
def __init__(self,x,y):
self.x = x
self.y = y
def distance(self):
print (self.x)
def bye(self):
print(self.y)
a=Point(1,2)
a.distance()
a.bye()
As i read in tutorial :
when we call a method with some arguments, the corresponding class function is called by placing the method's object before the first argument. So, anything like obj.meth(args) becomes Class.meth(obj, args).
when ObjectA.methodA(arg1, arg2) is called, python internally converts it for you as:
ClassA.methodA(ObjectA, arg1, arg2)
Now my confusion is why program need to call class with each method ?
Class.meth(obj, args) ??
like when we call a.distance it become Point.distance(a) causes of "self" when we called a.bye it become Point.bye(a) causes of "self" .
when Point class is necessery with each method if we don't use Point class with each method what will happen?
why can't simply meth(obj, args) works ?
My main doubt is why its called class.some_method with each method when we called with attribute of method . why its needs calls with each one?
#if i am understanding right then its necessary because so that each method can access other methods data like variables and stuff?
Upvotes: 2
Views: 493
Reputation: 781096
Because you can have the same method name in different classes, and it needs to call the appropriate one. So if you have
class Class1:
def meth():
print "This is Class 1"
class Class2:
def meth():
print "This is Class 2"
c1 = Class1()
c2 = Class2()
c1.meth() # equivalent to Class1.meth(c1)
c2.meth() # equivalent to Class2.meth(c2)
If it translated c1.meth()
to meth(c1)
, there's no way for the system to know which meth()
function to call.
Upvotes: 2
Reputation: 17041
The key is
python internally converts it for you
From your standpoint:
meth(self, args)
is the syntax you use to define member functions; andobj.meth(args)
is the syntax you use to call member functions. The meth(obj,args)
option is the way procedural languages work. That is often how the implementation works, but expressing the call as obj.meth(args)
keeps focus on the object and makes it easier to read which data values (object instances) are being used.
Edit 1 If I understand your question correctly, you are asking why Python needs to know the class when it already has the instance available, and instances know their own types. In fact, Python fetches methods based on the instance all the time. I think the point the tutorial is making is that in Python, the class is the primary place the functions are defined. This is different from some object-oriented languages, in which each instance has its own methods, and they may be completely different from each other. So the tutorial is contrasting the usual approach in Python:
class Foo:
def bar(self):
pass
with an alternative (possible in Python, but not typical):
foo = object() # an empty instance
foo.bar = lambda self: pass
Edit 2 Python methods normally live in the classes, not in the instances. Even if you create 1000 Point
objects, there is only one copy of the actual instruction bytes for Point.distance
. Those instruction bytes are executed anytime <some point variable>.distance()
is called. You are correct that the self
parameter is how those instruction bytes know what instance to work on, and how the method can access other data in the passed instance.
Edit 3 self
isn't exactly a namespace in the way that local vs. global is. However, it is fair to say that self.foo
refers to a foo
that is indeed accessible to all the methods of this instance of the current class. Given
a = Point(1,2)
b = Point(3,4)
inside a Point.distance
call, self
refers to a
or b
, but not both. So when you call a.distance()
, the self.x
will be a.x
, not b.x
. But all methods of Point
can access self.x
to get whatever the current point's x
is.
Edit 4 Suppose you weren't using objects, but instead dictionaries:
a = {'x':1, 'y':2} # make a "point"
b = {'x':3, 'y':4} # make another
def point_distance(point):
print (point['x'])
then you could say:
point_distance(a)
to get the effect of
print (a['x'])
Classes do basically that, with cleaner syntax and some nice benefits. But just as the point
parameter to point_distance()
refers to one and only one point-like dictionary each time you call point_distance()
, the self
parameter to Point.distance()
refers to one and only one Point
instance each time you call <whatever point>.distance()
.
Upvotes: 3
Reputation: 123473
Classes define what is common to all instances of them. Usually this is the code comprising each of its methods. To apply this code to the correct instance object, the language interprets
instance.method(arg1, arg2, ...)
as
class_of_instance.method(instance, arg1, arg2, ...)
so the code is applied to the proper class instance.
Upvotes: 1