bremen_matt
bremen_matt

Reputation: 7349

Python: Use private static method as default

I have a class member which accepts a function:

class A:

    def func(self, method):
       ...

I want to set a default method since that behavior is desired 99% of the time. This default behavior is static since it does not depend on any members of the class. However, I would like this default method to be private and invisible to the user. Is there any way of accomplishing that?

This is what I have tried:

  1. class A:
    
        @staticmethod
        def __meth(x):
           pass
    
        def func(self, method = meth):
           pass
    

    Error: 'staticmethod' object is not callable

  2. class A:
    
        @staticmethod
        def __meth(x):
           pass
    
        def func(self, method = A.__meth):
           pass
    

    Error: NameError: name 'A' is not defined

  3. class A:
    
        @staticmethod
        def __meth(x):
           pass
    
        def func(self, method = self.__meth):
           pass
    

    Error: NameError: name 'self' is not defined

I am using Python 3.5 and do not want to rely on newer features.

Upvotes: 2

Views: 3094

Answers (3)

llllllllll
llllllllll

Reputation: 16414

You can delay name resolution by putting it into a lambda:

class A:

   @staticmethod
   def __meth(x):
       pass

   def func(self, method = lambda s: A.__meth(s)):
       pass

Upvotes: 2

quamrana
quamrana

Reputation: 39384

The problems start with your default parameter. These parameters are evaluated whilst the class definition is being read, and so class A is not yet defined.

You should handle it like a normal default parameter:

class A:

    @staticmethod
    def __meth(x):
       print('meth')

    def func(self, method = None):
        if method is None:
            self.__meth(1)
        else:
             method()


def foo():
    print('foo')

a = A()

a.func()
a.func(foo)

Output:

meth
foo

Upvotes: 2

John Szakmeister
John Szakmeister

Reputation: 47032

It's fairly idiomatic to use None as the default and assign it as needed:

class A:

    @staticmethod
    def __meth(x):
        print(x)

    def func(self, method=None):
        if method is None:
            method = self.__meth

        method("x")

Upvotes: 3

Related Questions