2

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.

7
  • There is no private in Python. And if there were, it would be far from the desired default behavior. What you can get is name mangling. Do you really want to name mangle all your methods? Why?! Commented Apr 25, 2018 at 7:44
  • I understand that there is no "real" private. But I want to mangle the name so as to discourage its use for anything but this specific application Commented Apr 25, 2018 at 7:46
  • Just remove the @staticmethod decorator. Commented Apr 25, 2018 at 7:46
  • Wouldn't using a lambda be an option? Commented Apr 25, 2018 at 7:47
  • While that works, Lint starts to throw a bunch of warnings about how it should be static Commented Apr 25, 2018 at 7:47

3 Answers 3

3

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")
Sign up to request clarification or add additional context in comments.

Comments

2

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

Comments

2

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.