Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a __private static method from other methods in python

I'm assuming a private static method in a Python class is something that can and should be done. But perhaps in actuality, I should simply be using a module private method outside the class.

I want to understand calling different kinds of static methods from various locations:

I have a Python class with a private and a public static method. I want to call them from other places, and from each other.

When outside the class and calling the public static method, I must add the classname. i.e.

m = MyClass.the_staticmethod(100) # I must use the classname as a prefix

See questions in code:

    class Myclass():
        @staticmethod
        __my_privatestaticmethod(myparam):
             return myparam

        @staticmethod
        def the_staticmethod(myparam):
            # will the following work?
            result = __my_staticmethod(1) # will this work?

            # data-mingling set as private, so following line cannot work!
            result = Myclass.__my_staticmethod(2) # this cannot work. 

            result = the_staticmethod(3) # will this work without the prefix

            return result
 

        def __my_privatemethod(self, param1):
            # which of the following are valid?
            return __my_staticmethod(11) # will this work?

            # data-mingling set as private, so following line cannot work!
            return Myclass.__my_staticmethod(12) # this cannot work. 

            return the_staticmethod(13) # will this work without the prefix of the class? 
            
            return self.the_staticmethod(14) # will this work. Is the self also considered the class? 

            return  Myclass.the_staticmethod(15) # this of course works. 
            

        def the_method(param1):
            return __my_staticmethod(param1) # will this work?

If the answers to 1 and 11 are no, then the conclusion is that you cannot make a private static method.

I would then make a private module method outside the class without a decorator. This would be equivalent to the private static class method.

    def __my_privatemodulemethod(param1):
         return param1

and can call it from anywhere in my module, without a prefix.

like image 368
pashute Avatar asked Nov 06 '17 09:11

pashute


People also ask

Can you call a private static method from another class?

We can call the private method of a class from another class in Java (which are defined using the private access modifier in Java). We can do this by changing the runtime behavior of the class by using some predefined methods of Java. For accessing private method of different class we will use Reflection API.

How do you call a static method from another class in Python?

A static method is bound to the class and not the object of the class. Therefore, we can call it using the class name. A static method doesn't have access to the class and instance variables because it does not receive an implicit first argument like self and cls .

Can we call static method from another static method?

Characteristics of Static MethodsA static method can call only other static methods; it cannot call a non-static method. A static method can be called directly from the class, without having to create an instance of the class. A static method can only access static variables; it cannot access instance variables.


1 Answers

As deceze already mentionned in a comment, in Python a staticmethod is a method that doesn't take the instance nor the class as first argument. Since Python has no implicit this pointer, obviously a staticmethod has no way to reference the current class, so it cannot call another staticmethod on the current class. The obvious solution here is to use classmethods instead (classmethods takes the current class as first argument):

class Foo(object):
    @classmethod
    def _protected(cls, arg):
        print("{}._protected() called with {}".format(cls.__name__, arg))

    @classmethod
    def public(cls, arg):
        cls._protected(arg)

there IS a notion of private/public achieved with data mingling

s/data mingling/name mangling/g ;)

"dunder" names and the name mangling mechanism don't make anything private:

class Foo(object):
    @staticmethod
    def __not_private():
        print("peek a boo")


Foo._Foo_not_private()

As the "clunky" doc states, the point here is mostly to avoid accidental overridding of some important implementation part of a base class. Practically this is very seldom used, and most of the time not even really needed. The convention to indicate "implementation" methods and attribute is to name them with a single leading underscore.

As a side note, snarky remarks about Python's doc quality is not going to get you much helping friends.

like image 170
bruno desthuilliers Avatar answered Sep 27 '22 20:09

bruno desthuilliers