Expose modules from python file

Hi,

In my python file, there many functions, classes, global variables and etc.
take the following code piece as an example.

I would like to make func1 callable by upper user, and func2 and data class couldn’t be callable by upper user.
is there a method to do that?

def func1():
    return

def func2():
    return

class data():
    def __init__(self):
        pass

What do you mean by “upper user”?

If you are looking for “private” classes and methods like in Java, the
answer is no. We have a strong convention that anything named with a
single leading underscore is private, otherwise it is public.

1 Like

Thank you, Steven!

:upper user: means other code that use my python file.
I will try a function in a python file with name which is a single leading underscore.

In the following python file abc.py, the function with name which is a single leading underscore could be called by outside of abc.py file.

my question is: I would like to make _func__1 not callable outside of the abc.py file.

def func__1():
    print('fun name =={}'.format(func__1))

def _func__1():
    print('fun name =={}'.format(func__1))

This is one way to do it. Very un-Pythonic, but possible

def _init_module():
    global func

    def func():
        inner()

    def inner():
        print("hello")

_init_module()
del _init_module # stealth mode

The Pythonic way is to define __all__ = ['list', 'of', 'exported', 'names'] to control what import * sees.

1 Like

Thank you Daniel!

the way you mentioned is not what I want.
I seems that there is no way in Python to make some funcitons in a file to not be callable outside.

1 Like

Why do you care?

If you don’t want to call a function in a module, just don’t call it.

I have dozens of scripts that import the math module, but I don’t want
to call math.tan so I just don’t call it.

What is the actual problem you are trying to solve?

Hi Steven,

what I care is what I firstly posted in the topic:
There are many modules(classs, functions, global variables) in a file.
some should be called by others, some should not be called by others. If all modules are exposed to others, it might mislead others.
So what I care is to make some modules could be called by others, and make some some modules could not be called by others.

What do you mean by “mislead others”?

Do you mean that you might write a function called “print_list”, and
people will think it prints the list, but it actually sorts it instead?

The solution to that is to not give functions misleading names. If the
names describe what the function does, and they have good documentation
in their docstring, then they won’t mislead others.

I think I asked before if you mean something like “private” methods in
Java, but I haven’t seen an answer. If that is what you mean, the way to
do that in Python is to give your functions a name starting with a
leading underscore. Now everyone will know that it is a private function
not to be used.

The same applies to classes and modules.

And if they still use it? Okay, so what? Why do you care?

There is no way in Python to prevent a function from being called by
another module. If the other module can get access to the first module,
it can call anything it likes.

Python is not a language designed for people who think of their users as
the enemy. You don’t have to protect me from breaking things. I can
import a module and totally destroy it if I want to:

import math
math.sin = "surprise!"
del math.sqrt, math.cos, math.factorial
math.something_new = lambda x: x + 2
math.nan = 2.5
math.exp = math.tan
math.tan = math.atan
del math.atan
math.ceil, math.floor = math.floor, math.ceil
math.erf = 99.1

There you go – I have broken the math module. The only person I have
hurt by doing that is me.

To fix it, all I need to do is exit the interpreter and start it again,
and the math module is back to normal.

I think you are worrying too much about protecting against things that
aren’t problems. If I want to break the module, and make it unusable,
it’s not your job to stop me.

1 Like

what you said is almost the same as what I meant. not only function name, Let me give an example:
in python file, there are function:
get_gpu_list()
get_idle_gpu_list()
get_available_gpu_list()
get…
many similar function. the only function that other user should call is get_gpu_list. if all functions are exposed to user who might have to think of what should be used and what is the meaning of each function.

in class of python, function name with leading single underscore is very good for my idea.
however, the leading single underscore method doesn’t work for function in python file.

Ardeal gave an example:

get_gpu_list()

get_idle_gpu_list()

get_available_gpu_list()

"… many similar function. the only function that other user should

call is get_gpu_list."

What if the user wants, not all gpus, but only the idle gpu list?

You said:

"if all functions are exposed to user who might have to

think of what should be used and what is the meaning of each function."

Oh no, the user might have to think about what they are doing!!!

They already have to think about it. If they want the list of GPUs, it

is no good for them to call len() or random.random(). What if they want

a list of CPU cores instead of GPUs?

You will never have a situation where the user doesn’t have to think

about which function to call. That is impossible.

"in class of python, function name with leading single underscore is

very good for my idea. however, the leading single underscore method

doesn’t work for function in python file."

Of course it does. Look at any module in the Python standard library,

and you will likely find it using single underscore functions.

There are single-underscore modules, and regular modules that have

single underscore functions.

are just a few examples.

[…]

in class of python, function name with leading single underscore
is very good for my idea. however, the leading single underscore
method doesn’t work for function in python file.

Can you elaborate? I have plenty of working, published, and quite
widely-used Python modules containing top-level functions whose
names begin with an underscore. I do this expressly to indicate that
they’re not part of the module’s stable API, and thus external
callers are unsupported. This is, in fact, quite a common convention
in the Python ecosystem, and not just for class methods.

The correct answer is to structure your code according to the uses it’s going to be put: sticking all your functionality into a single module isn’t necessarily a good idea. To a first level of approximation (approxymation?), if you have a module m that defines symbols a, b and c, and you write a proxy_m module that imports a and b from m (literal code: “from m import a, b”) and then tell the user to use proxy_m. You could define several different proxy modules for different use cases.