menw
menw

Reputation: 41

what is the difference between these two method?

class Person:
    def __init__(self, name):
       self.name=name

    def talk(self):
       print(f'I am {self.name}')

p1=Person('John')
Person.talk(p1)  ---  (1)
p1.talk(p1)   --- (2)

I just learned about class, instance, method about few days ago, but can't understand this part. Well I can understand the first one(1) that the code will be read it like class Person-> method talk->self and will print I am John.

But why the second one(2) has an error? The error says talk() takes 1 positional argument but 2 were given.

Aren't the two same? Why the second one gives 2 argument?

Upvotes: 1

Views: 103

Answers (3)

Rinshan Kolayil
Rinshan Kolayil

Reputation: 1139

Following code will meet your concern, and you can refer other answers as well, because the error message was TypeError: talk() takes 1 positional argument but 2 were given

class Person:
    def __init__(self, name):
        self.name=name
    def talk(self,variable=None):
        if isinstance(variable, Person):            
            print(type(variable))
            print(variable.name)
            variable.talk("call from class")
            # if i pass an instance class person here, it will continue to infinite loop. 
            # i.e. do not pass like variable.talk(variable)
        else:
            print(variable)
        print(f'I am {self.name}')

p1=Person('John')
Person.talk(p1) 
p1.talk(p1)
# or p1.talk() or Person("John").talk("") 

And output was

#Person.talk(p1)
#=================
None
I am John
#p1.talk(p1)
#==================
<class '__main__.Person'> #print(type(variable))
John #print(variable.name)
call from class #print(variable)
I am John #print(f'I am {self.name}') # Since i make call to itself inside
I am John #print(f'I am {self.name}')

Upvotes: -1

vszholobov
vszholobov

Reputation: 2363

self in Python class

Python decided to do methods in a way that makes the instance to which the method belongs be passed automatically, but not received automatically: the first parameter of methods is the instance the method is called on.

You can name this parameter whatever you like

class Person:
    def __init__(_, name):
       _.name=name

    def talk(_):
       print(f'I am {_.name}')

Example

>>> p = Person("test")
>>> p.talk()
I am test

In your example you get error, because you try to call method with one parameter def talk(self): with two parameters(self is obtained automatically plus you give your variable).

Also, as @Eladtopaz mentioned, if you call method from class, instead of instance, method won't receive self

Person.talk()
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
Person.talk()
TypeError: talk() missing 1 required positional argument: '_'

but we still can provide Person instance manually

>>> Person.talk(Person("Hard test"))
I am Hard test

Upvotes: 3

Eladtopaz
Eladtopaz

Reputation: 1054

There is a difference between using a method of a class:

  1. with the class name
  2. with only an instance of the class When you use the class name like this: class_name.function_name(self) Then you always have to pass on an instance of the class too, because, the method also gets an instance, called self right?

But, when you use the second option: instance_name.function_name(self) The method automatically takes the instance that activates the method using the . and uses it as it was the first argument that was passed on to the method. in this case, your talk method takes only1 parameter and it is an instance of the class, so when you use:

p1.talk()

Then p1 will pass on automatically as that parameter and if you add another thing in the parentheses, you get your error because the method doesn't get another parameter, only 1.

Upvotes: 1

Related Questions