'Why is Class function working if class is mentioned in function call but not if the object instantized is used in function call in python? [duplicate]
The above code works but the second code shows typerror: print(a.factorial(a, 5))TypeError: factorial() takes 2 positional arguments but 3 were given:
class Factorial:
def factorial(self, num):
if num == 0:
return 1
if num ==1:
return 1
else:
return num * self.factorial(self, num-1)
def main():
a = Factorial()
print(Factorial.factorial(Factorial, 5))
main()
The second code is as follows:
class Factorial:
def factorial(self, num):
if num == 0:
return 1
if num ==1:
return 1
else:
return num * self.factorial(self, num-1)
def main():
a = Factorial()
print(a.factorial(a, 5))
main()
Solution 1:[1]
self argument is the same as the object on which you call the function. You don't need to provide it again as the first explicit argument - a.factorial(5) will work.
Solution 2:[2]
When you call a method on an instance (rather than on the class), the instance is automatically passed as the self argument. You don't pass it yourself.
So this:
Factorial.factorial(a, 5)
is the same as this:
a.factorial(5)
and this:
a.factorial(a, 5)
is the same as this:
Factorial.factorial(a, a, 5) # too many arguments!
Note that your function definition is also confused about the difference between instances and classes. Given that this is an instance method, it should expect self to be an instance of Factorial, not the Factorial class itself:
def factorial(self, num):
if num == 0:
return 1
if num ==1:
return 1
else:
return num * self.factorial(num-1) # no extra "self" arg
Once you make this fix, calling this method as Factorial.factorial(Factorial, 5) will not work, because that's not a valid way to call an instance method (it "works" in your current code because of that self bug that prevents it from working as an actual instance method).
To define it as a class method (where the first argument is the class, not an instance), you'd do:
@classmethod
def factorial(cls, num):
if num == 0:
return 1
if num ==1:
return 1
else:
return num * cls.factorial(num-1)
and then would call it as Factorial.factorial(5).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | matszwecja |
| Solution 2 |
