1

Let's say I have a class (in python3.6)

class Testing:

    def __init__(self, stuff):
        self.stuff = stuff

    @staticmethod
    def method_one(number):
        """My staticmethod"""
        return number + 1

    def method_two(self):
        """Other method"""
        number = 10

        # option A
        self.method_one(number)

        # option B
        Testing.method_one(number)

What is more python here?

  • option A, using the self var
  • option B, using the class itself

I tend to think A, but I am unsure and couldn't find a solid answer on the topic

Wesley Bowman
  • 1,366
  • 16
  • 35
  • 1
    `staticmethod`s work without an instance and can be used for example as factories. Instance-bound ("self") methods have an instance context they can work with. It's really more about what you have and need instead of pythonic or not. Both have their specific applications where they fit better than the other. – Jeronimo Feb 09 '18 at 09:29

3 Answers3

3

In the case of static methods I would always prefer notation B over notation A. The main reason for this is that notation B tells me something about the method that I wouldn't have known if you used notation A.

If you use the class name instead of self it is immediately obvious to the reader that they are dealing with a static method. This way the reader knows that the method doesn't use or change the class or instance state. If you use self you have to check the actual method to see if the class or instance state is used.

1

In fact using self is not good in static methods. so when you want to call static methods you can use option B , with class object.

So for calling other methods means non static here is the strategy :
If both methods are in same class you can use self like you mentioned in option A.

option B(which means calling a methodinside a class... using class object) , you can use when function that you want to call is in another class

UPDATE :

For calling static methods in the same class you can use two ways,other than self. They are more pythonic.
1. call from class : classname.static_method_name()
2. call from instances
these two ways are more pythonic than self. So in your case option B is more pythonic.

Vikas Periyadath
  • 3,088
  • 1
  • 21
  • 33
  • I was specifically asking about this example, where I just use this staticmethod in the same class. Also note, the method that is the `staticmethod` doesn't rely on `self` at all. Also, I know I can use both ways, just was wondering what is more pythonic – Wesley Bowman Feb 09 '18 at 07:58
  • 1
    @NightHallow i have updated my answer, reply where you need clarification. – Vikas Periyadath Feb 09 '18 at 08:56
  • Happy to accept as the answer, just wondering if there is a reason why it's more pythonic. I could assume that option B was more, but at the same time, if the staticmethod is only ever used in the same class it's created in, I would almost think that `self` is more readable. I didn't know if there is a PEP or somewhere that discusses this. Also, thank you for your time – Wesley Bowman Feb 09 '18 at 09:09
  • @NightHallow usually we are giving the things in static method not much related to class or else around it and doesn't want to know class status. That's why it doesn't accept self as argument. So when calling with object static method python simply enforces the access restrictions of other variables or anything than calling with self. Basically static methods doesn't need of self objects, So by calling with class object they restricting access of self. I think here you will get a [detailed explanation](https://realpython.com/blog/python/instance-class-and-static-methods-demystified/) . – Vikas Periyadath Feb 09 '18 at 09:39
  • Once again, I understand staticmethods. My question is more centered around the mythical "pythonic". But I have gleaned enough information here to get a reasonable assumption as to why – Wesley Bowman Feb 09 '18 at 12:53
1

For me Option B has the disadvantage that it explicitly uses the class name Testing again. If the class is renamed (or contents are copy/pasted), this needs to be updated. Using

type(self).method_one(number)

seems a way if one really wants to highlight that this is not an instance method.

Note that this gives you your own class. If your class overwrites a static method of the parent class with and instance method that has the name name, then the call will fail. Using super().some_static_method() will work, but since super() returns a proxy object type(super()).some_static_method() does not work.

So practically, using self seems ok if all you care about is accessing your (currently set) method. A class instance also "inherits" the class-methods and static methods of parents. But if you really want to invoke the static method from Testing regardless of what instance you are currently in, then use Testing.method_one(). It's a bit hard to argue about the most "pythonic way" when the whole class/inheritance design can be questioned also...

Axel Heider
  • 557
  • 4
  • 14