What it really means "from modulox import *"

Asked

Viewed 74 times

5

As far as I know it matters all the classes and functions of a certain file without having to reference it in the code, right? But I’m beginning to think from modulo import * doesn’t mean that.

I was studying the Tkinter library and came across the following situation:

from tkinter import *
from tkinter import colorchooser

If in the first import has already used the *, why would I need to import the colorchooser again? In fact apparently the colorchooser nor was imported.

If I try to use the colorchooser without using the second line it simply says it is not set. Why you need to import twice the colorchooser?

2 answers

6

You don’t matter twice. Using the asterisk does not necessarily mean that you will import all available classes, functions or variables within a module. Then we have two cases...

  1. The variable was not defined __all__ on file __init__py., then Python will load whatever is set inside (which can’t be the best of behaviors), or

  2. Import all that is deemed necessary and has been defined within __all__, which gives you much more control over what is being carried.

For example you have a module called module and in its directory there are two files, one containing the classes, the py sums.:

class Media:
    ...

class Soma:
    ...

And the other the __init__py. which even indicates that this directory is a module:

__all__ = ("Media",)

from .somas import Media, Soma

In this scenario if you do:

>>> from modulo import *
>>> a = Media()
>>> b = Soma()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Soma' is not defined

You can’t use class Soma for only Media was automatically loaded.

It is necessary to load it manually (in this case only of the class Soma):

>>> from teste import Soma
>>> b = Soma()

Or, depending on the case, adding it within __all__.

  • I don’t know if I got it right, so when you import from a library, when you use *, it imports everything that’s in the file init.py of that folder? then Tkinter would not be a "Tkinter.py" file but a folder?

  • The asterisk in the case we’re talking about, will matter the __init__.py package (folder) tkinter if he exists. But the asterisk itself imports the data only from the specified module, as I said in my reply https://answall.com/a/440593/157404

5

Use the asterisk (*) will yes import all data (variables, functions and classes) from the module you specified in from, having no other purpose.

What happens is that by doing from tkinter import *, you are importing from the package tkinter the file __init__.py. And unlike what you think, the colorchooser is not inside the file that you matter, as it is another module inside the package.

Therefore, if you only perform the first import, you will not be able to access the colorchooser and consequently a NameError.

from tkinter import *             # Aqui você importa tudo do __init__.py
from tkinter import colorchooser  # Aqui você importa o módulo colorchooser.py do pacote

You can prove that the colorchooser is a module using the function help.

>>> help(colorchooser)
Help on module tkinter.colorchooser in tkinter:

NAME
    tkinter.colorchooser
...

Behold here the contents of the package. You can also see the contents by going to the directory <python_path>/lib/tkinter or running help(tkinter) to look at the documentation.

  • In this case, if the init.py n existed. it would import everything from the Tkinter folder?

  • No, you would just import the package with your information. You can even do this test by creating your own package and whether or not to put the file __init__ to see what comes out.

  • Just one more question, if you have a package and inside that package you have a folder. By importing it using asterthis folder would be imported tbm?

  • No. Let’s say there’s the folder modulo2 inside modulo1. In that case the import to obtain only the data of modulo2 would be from modulo1.modulo2 import *. Unless of course you already made an import with the __all__ within the modulo1.

  • Thank you very much, apparently I have a lot to learn haha

  • 2

    It would be legal to grow in response that the recommendation is never use from x import *: This makes it difficult to maintain (you don’t know where a variable or function originated from), and even clutters up the Ides' self-completed features - plus you have a great chance of name conflict. The ideal is to either import all the names explicitly, or import the module, possibly with a shortened name - and always use the prefix. For example: import tkinter as tk; button=tk.Button(...)

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.