Eleutetio
Eleutetio

Reputation: 139

Why we need corresponding class function with each method in python?

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

Answers (3)

Barmar
Barmar

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

cxw
cxw

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; and
  • obj.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

martineau
martineau

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

Related Questions