-1
class MyClass:
    def func1(a,b):
         print(a,b)

MyClass.func1(4,5)

I thought the above piece of code will throw error because we are accessing a method that is declared without @staticmethod decorator using class.

So does that mean the function called with class name will act like a static method ?

Aji C S
  • 71
  • 7
  • If you don't put self as a parameter I believe that func1 implicitly is a class method – Richard K Yu Feb 11 '22 at 13:50
  • 1
    @RichardKYu, that is not correct - (i) `self` is just the convention, and (ii) `classmethod` is something different from `staticmethod` – buran Feb 11 '22 at 13:51
  • 1
    It works because you don't call it on instance, e.g. `MyClass().func1(4, 5)` (that would pass the instance explicitly as `a`). and you pass as many arguments as there are params. You just access (call) attribute. Note that using it like this more or less makes it pointless to put the function inside a class. – buran Feb 11 '22 at 13:56
  • @buran What type of function would func1 be in this case? I got the idea since I was reading the second answer on [this page](https://stackoverflow.com/questions/735975/static-methods-in-python). I guess the idea is that self doesn't make a difference? – Richard K Yu Feb 11 '22 at 13:58
  • 1
    @RichardKYu, this is instance method (it is not explicitly declared as `@staticmethod` or `@classmethod`) and it can be called on instance `MyClass().func1(4, 5)`, in which case instance will be passed as first argument `a`, 4 will be `b` and then will be error, because it expects 2, but got 3 arguments. – buran Feb 11 '22 at 14:03

2 Answers2

0

You can access functions of a class from the class name itself, there is no need to create an object or use @staticmethod. MyClass is similar to str both are classes. Consider the following example:

class MyClass:
    def func1(a,b):
         print(a,b)

print(type(MyClass)) #types are the same
print(type(str)) #types are the same
x = str.__add__('test', " best") #you can use str.__add__ without using str objects
print(x) #output: test best

The output in your example works for the same reason this does. 'test' + " best" just calls __add__ just like o = MyClass() would create an object that could call func1. You are just accessing the functions that are stored in these classes and calling the function directly without assigning an object first and using the method within that object.

In this case the class is just a holder for the function. If this was the intended use you would most likely want to use a normal function rather than making in a class attribute.

Eli Harold
  • 2,280
  • 1
  • 3
  • 22
0

Yes, if used as a class property, there is no special mechanism instated to use it as a method:

>>> class A:
...     def f(a, b):
...         print(a,b)
...
>>> type(A.f)
<class 'function'>

However:

>>> a=A()
>>> type(a.f)
<class 'method'>
>>> a.f('only one arg because a itself is supplied as first arg')
<__main__.A object at 0x76992b70> only one arg because a itself is supplied as first arg

When a plain (no staticmethod, no classmethod) function defined inside a class is called through an instance of the class, then it is called as a method, meaning the first argument (in this case a but typically self) will be automatically provided as the instance itself.

tzot
  • 92,761
  • 29
  • 141
  • 204