1

(I've checked out Does Python have “private” variables in classes? -- it asks about classes rather than modules. As such, answers there don't cover import which is what I'm interested in.)

Consider, there is a module called X with variable y. If any other module tries to import the module X, how to avoid loading the variable y in Python?

For example:

# x.py
y=10

We then use this in some other module:

import x 
print x.y

How to avoid accessing x.y from the module x.py ?

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
tamil
  • 381
  • 1
  • 2
  • 9
  • Is there any side-effect on loading variable `y`? Do you know about the `__all__` variable? – memoselyk Dec 20 '15 at 16:35
  • @memoselky, yes, I want to hide particular variable being imported in a module and I don't know about `__all__` – tamil Dec 20 '15 at 16:41
  • Some example code would vastly improve this question. It is unclear what the precise need is. – msw Dec 20 '15 at 16:42
  • 1
    The moderators for this question who marked it as a duplicate of "Does Python have 'private' variables in classes?" apparently don't know Python. This question is NOT a duplicate of that question. The moderators are apparently so ignorant of Python that they don't know the difference between a "class" and a "module". This state of affairs is pretty sad if you ask me. The correct answer, btw, was provided here below by ivan_pozdeev. – Douglas Nov 15 '18 at 19:53

2 Answers2

4

If you do import module, there's no way to hide any global members, and that's intentional: the module object returned is the "true" one, the very same that's used by the module's members. Dirty hacks like __getattr__ are also prohibited for modules.

One way is to mark "internal" entities with a leading underscore to hint the user they are not intended for external use. This isn't necessary for references to other modules imported by yours since the guidelines explicitly discourage external use of them (the only exception is if the referenced module is inaccessible the normal way).

When doing from module import *, however, you don't get a module reference but import things from it directly into the current namespace. By default, everything except names starting from an underscore is imported. You can override this by defining the __all__ module attribute.

Community
  • 1
  • 1
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
1

In normal use import foo only imports the module once; all other imports see that it has been imported, and doesn't load it again.

Quoth https://docs.python.org/3/reference/import.html#the-module-cache:

During import, the module name is looked up in sys.modules and if present, the associated value is the module satisfying the import, and the process completes. However, if the value is None, then an ImportError is raised. If the module name is missing, Python will continue searching for the module.

This has been long been a feature of the interpreter going back at least to version 2.7 and probably earlier.


Speaking to your specific question, there is no variable y, there is x.y because that's what you imported. If you do the highly unrecommended from module import * you can end up with a y, but you shouldn't do that.

msw
  • 42,753
  • 9
  • 87
  • 112