6

I'm writing an program where im using two main functions however those both functions uses same inner functions. I'm wondering how I should write them in most pythonic way? My point is to hide those helpers somewhere inside and to dont repeat helper functions.

def main_function1():
    helper1()
    helper2()
    #dowork1

def main_function2()
    helper1()
    helper2()
    #dowork2

def helper1()
    #workhelp1

def helper2()
    #workhelp2

The only reasonable solution which i can figure out is declaring static class with.. private functions? But since:

Strictly speaking, private methods are accessible outside their class, 
just not easily accessible. Nothing in Python is truly private[...]

Im stuck and out of ideas.

From: http://www.faqs.org/docs/diveintopython/fileinfo_private.html

Topic: Why are Python's 'private' methods not actually private?

Also I thought about declaring one main function with inner helpers and with switcher as a argument to determine which function should run but I guess thats pretty poor solution.

For now only way I find the most accurate is to declare normal class as:

class Functions:
    def main_function1(self):
        print("#first function#")
        self.helper1()
        self.helper2()

    def main_function2(self):
        print("#second function#")
        self.helper1()
        self.helper2()

    def helper1(self):    
        print("first helper")

    def helper2(self):
        print("second helper")

Functions().main_function1()
Functions().main_function2()
print("###")
Functions().helper1()

Output:

#first function#
first helper
second helper
#second function#
first helper
second helper
###
first helper

But also here i can access helpers which isnt a big deal but still gives me a reason to wonder.

sobczi
  • 121
  • 7
  • 1
    I guess naming convention should do just fine, name It `__helper` and declare just as regular function without nesting. – kravitz Mar 24 '19 at 03:18

2 Answers2

4

There are no private functions in Python. Rather, by prefixing the names of methods intended to be non-public with underscores, you signal to users of your class that those methods are not meant to be called externally:

class Functions:
    def main_function1(self):
        print("#first function#")
        self._helper1()
        self._helper2()

    def main_function2(self):
        print("#second function#")
        self._helper1()
        self._helper2()

    def _helper1(self):    
        print("first helper")

    def _helper2(self):
        print("second helper")

This is in line with the principle of "We're all consenting adults here" - you can touch the non-public methods of a class, but if you use them wrongly, that's on your own head.

gmds
  • 19,325
  • 4
  • 32
  • 58
0

Try this

def get_main(name):
    def helper1():
        print("helper1")
    def helper2():
        print("helper2")
    def main1():
        print("Running helpers from main1")
        helper1()
        helper2()
    def main2():
        print("Running helpers from main2")
        helper1()
        helper2()
    if name == "main1":
        return main1
    if name == "main2":
        return main2


main1 = get_main("main1")
main2 = get_main("main2")

You can then run the function as follows:

main1()
main2()
helper1()

output:

Running helpers from main1
helper1
helper2
Running helpers from main2
helper1
helper2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'helper1' is not defined
Nitro
  • 1,063
  • 1
  • 7
  • 17
  • That's Python 2 (`print` as a statement instead of as a function) *and* won't work because your indentation is faulty. – gmds Mar 24 '19 at 03:55
  • @gmds : I am trying to give an idea of the concept. Will add the same for python3 if it confuses people. – Nitro Mar 24 '19 at 04:00
  • 1
    Since Python 2 is nearing its end-of-life (next year), it would probably be better if you used Python 3 syntax (especially since, in this case, it would still work for Python 2). In any case, without fixing the indentation errors, your code will not work at all. – gmds Mar 24 '19 at 04:01
  • Apologies for the indentation. I answered the question via the mobile app. Corrected it now. – Nitro Mar 24 '19 at 04:04