Why must I import before I can call a module - python

I am new to Python and am not sure why you must import before you can call a module or function. Does anyone have an answer to this? And thanks in advance. An example would look like:
import random
randomNum = random.randint(0,1)

You must import a module in Python before you use a method from it because otherwise, the interpreter doesn't know what to do when you call a method from said module. Some functions in python, like print() can be called without importing any modules, but for others like random.randint(), the module isn't imported by default, so you need to import it before use.

Practically, random and math and all of those classes that you need to import are actually other Python files. They are code, written by the people that made Python, and designed to make your job easier.
Think of import as just copy-and-pasting the source code from those modules to the top of your program. It just means that your code can now use all of that code, too. The reason that it is not all imported by default is thus because there would be a lot of overhead from all of those modules, when you might not even use them.
Without importing, the interpreter wouldn't know what to do when you used a function from random (or any other imported module), because it wouldn't have the code to do it.
Likewise, you can actually import your own code if you wanted to. So if, for example, you made a really cool implementation of a stack, you could import that code that you wrote into your other Python files so that you can also use it in those.
Read more about import: https://docs.python.org/3/reference/import.html

Related

Best practice for writing own functions with imported modules in Python?

I am trying to write my own functions/methods in a tools.py module for an ongoing project.
I need to import some modules like numpy for these methods, but am unsure of the best way to do this. Should I import within each method each time I call that function? Or in the tools.py script at the beginning? I do not always need all the functions in tools.py, and for example, don't always need numpy in the script where I call import tools. I would like my code to be as efficient as possible.
I only found info that I need not import numpy if I do not call it directly in a specific script.
You could allways import only specific functions or classes of a module, i.e.:
from tools import myfunction
Further it is correct that you dont import numpy if you dont need it. However
as far as my experience goes, imports of imports are not available in the current script.
This means when your tools.py contains the import numpy, and you load your tools in another script main.py, numpy (i.e. numpy.array()) wont be available in main.py. You would need to import it there as well.
However you can also import modules inside of functions to reduce the visibility and initial start up time of a script, see also this link
Some general performance tips are also provided here
This said, in general modern computers have evolved so far that imo in most use cases you dont need to worry to much about performance
I could be wrong, but I'm pretty sure importing a module loads the entire thing whether you use import sys or from sys import argv. So, importing numpy into the tools module will make the entire numpy module available to the tools module and, though not directly callable, wherever the tools module is imported into. I've only seen imports within a function to achieve optional library support. I hadn't heard of it being done for the sake of efficiency nor performance.
These links may help further:
Should import statements always be at the top of a module?
https://softwareengineering.stackexchange.com/q/187403
You shouldn't by importing numpy at every method call. This should only be done once at the start of your script. If you don't want to import the entire module in tools.py, just import specific submodules you need from the library:
from numpy import submodule1, submodule2

How to define a function which imports modules

I am trying to define a function which imports modules and place that function in a module of my own so that when I am working on a certain type of project all I need to type is:
import from user *
setup()
#setup is the function which imports the modules
However, whenever I try this, it simply doesn't work. trying to call upon the modules defined in setup after I have run the function only results in an error saying that the modules aren't installed.
Here is the code in my module:
def setup():
import keyboard, win32api, win32con
Let me know if there is any more information I can provide, and thanks for any help.
It's generally a good idea to explicitly import names into your module where you need them, so you can see where things come from. Explicit is better than implicit. But for interactive sessions, it can sometimes be useful to import loads of things at once, so...
You problem is that your setup method imports these modules into its own namespace, which isn't available outside the function. But you can do something much simpler. If your user module just contained:
import keyboard, win32api, win32con
Then in your interactive session you could do:
>>> from user import *
These modules should then be available in your session's namespace.
I think you are having a scope problem, if setup is defined in some other module, the import will be valid in that module only (or maybe only in the function that would need to be tested).
As a general matter an "import everything possibly needed" policy is something I would consider wrong. Your code ought only to import what it really needs. Dependencies are better reduced to a minimum and explicit.

Circular imports hell

Python is extremely elegant language. Well, except... except imports. I still can't get it work the way it seems natural to me.
I have a class MyObjectA which is in file mypackage/myobjecta.py. This object uses some utility functions which are in mypackage/utils.py. So in my first lines in myobjecta.py I write:
from mypackage.utils import util_func1, util_func2
But some of the utility functions create and return new instances of MyObjectA. So I need to write in utils.py:
from mypackage.myobjecta import MyObjectA
Well, no I can't. This is a circular import and Python will refuse to do that.
There are many question here regarding this issue, but none seems to give satisfactory answer. From what I can read in all the answers:
Reorganize your modules, you are doing it wrong! But I do not know
how better to organize my modules even in such a simple case as I
presented.
Try just import ... rather than from ... import ...
(personally I hate to write and potentially refactor all the full
name qualifiers; I love to see what exactly I am importing into
module from the outside world). Would that help? I am not sure,
still there are circular imports.
Do hacks like import something in the inner scope of a function body just one line before you use something from other module.
I am still hoping there is solution number 4) which would be Pythonic in the sense of being functional and elegant and simple and working. Or is there not?
Note: I am primarily a C++ programmer, the example above is so much easily solved by including corresponding headers that I can't believe it is not possible in Python.
There is nothing hackish about importing something in a function body, it's an absolutely valid pattern:
def some_function():
import logging
do_some_logging()
Usually ImportErrors are only raised because of the way import() evaluates top level statements of the entire file when called.
In case you do not have a logic circular dependency...
, nothing is impossible in python...
There is a way around it if you positively want your imports on top:
From David Beazleys excellent talk Modules and Packages: Live and Let Die! - PyCon 2015, 1:54:00, here is a way to deal with circular imports in python:
try:
from images.serializers import SimplifiedImageSerializer
except ImportError:
import sys
SimplifiedImageSerializer = sys.modules[__package__ + '.SimplifiedImageSerializer']
This tries to import SimplifiedImageSerializer and if ImportError is raised (due to a circular import error or the it not existing) it will pull it from the importcache.
PS: You have to read this entire post in David Beazley's voice.
Don't import mypackage.utils to your main module, it already exists in mypackage.myobjecta. Once you import mypackage.myobjecta the code from that module is being executed and you don't need to import anything to your current module, because mypackage.myobjecta is already complete.
What you want isn't possible. There's no way for Python to know in which order it needs to execute the top-level code in order to do what you ask.
Assume you import utils first. Python will begin by evaluating the first statement, from mypackage.myobjecta import MyObjectA, which requires executing the top level of the myobjecta module. Python must then execute from mypackage.utils import util_func1, util_func2, but it can't do that until it resolves the myobjecta import.
Instead of recursing infinitely, Python resolves this situation by allowing the innermost import to complete without finishing. Thus, the utils import completes without executing the rest of the file, and your import statement fails because util_func1 doesn't exist yet.
The reason import myobjecta works is that it allows the symbols to be resolved later, after the body of every module has executed. Personally, I've run into a lot of confusion even with this kind of circular import, and so I don't recommend using them at all.
If you really want to use a circular import anyway, and you want them to be "from" imports, I think the only way it can reliably work is this: Define all symbols used by another module before importing from that module. In this case, your definitions for util_func1 and util_func2 must be before your from mypackage.myobjecta import MyObjectA statement in utils, and the definition of MyObjectA must be before from mypackage.utils import util_func1, util_func2 in myobjecta.
Compiled languages like C# can handle situations like this because the top level is a collection of definitions, not instructions. They don't have to create every class and every function in the order given. They can work things out in whatever order is required to avoid any cycles. (C++ does it by duplicating information in prototypes, which I personally feel is a rather hacky solution, but that's also not how Python works.)
The advantage of a system like Python is that it's highly dynamic. Yes you can define a class or a function differently based on something you only know at runtime. Or modify a class after it's been created. Or try to import dependencies and go without them if they're not available. If you don't feel these things are worth the inconvenience of adhering to a strict dependency tree, that's totally reasonable, and maybe you'd be better served by a compiled language.
Pythonistas frown upon importing from a function. Pythonistas usually frown upon global variables. Yet, I saw both and don't think the projects that used them were any worse than others done by some strict Pythhonistas. The feature does exist, not going into a long argument over its utility.
There's an alternative to the problem of importing from a function: when you import from the top of a file (or the bottom, really), this import will take some time (some small time, but some time), but Python will cache the entire file and if another file needs the same import, Python can retrieve the module quickly without importing. Whereas, if you import from a function, things get complicated: Python will have to process the import line each time you call the function, which might, in a tiny way, slow your program down.
A solution to this is to cache the module independently. Okay, this uses imports inside function bodies AND global variables. Wow!
_MODULEA = None
def util1():
if _MODULEA is None:
from mymodule import modulea as _MODULEA
obj = _MODULEA.ClassYouWant
return obj
I saw this strategy adopted with a project using a flat API. Whether you like it or not (and I'm not sure about that myself), it works and is fast, because the import line is executed only once (when the function first executes). Still, I would recommend restructuring: problems with circular imports show a problem in structure, usually, and this is always worth fixing. I do agree, though, it would be nice if Python provided more useful errors when this kind of situation happens.

how to test if one python module has been imported?

How to test if a module has been imported in python?
for example I need the basics:
if not has_imported("sys"):
import sys
also
if not has_imported("sys.path"):
from sys import path
Thanks!
Rgs.
Thanks for all of your comments:
the code been pasted here.
auto import all sub modules in a folder then invoke same name functions - python runtime inspect related
If you want to optimize by not importing things twice, save yourself the hassle because Python already takes care of this.
If you need this to avoid NameErrors or something: Fix your sloppy coding - make sure you don't need this, i.e. define (import) everything before you ever use it (in the case if imports: once, at startup, at module level).
In case you do have a good reason: sys.modules is a dictionary containing all modules already imported somewhere. But it only contains modules, and because of the way from <module> import <variable> works (import the whole module as usual, extract the things you import from it), from sys import path would only add sys to sys.modules (if it wasn't already imported on startup). from pkg import module adds pkg.module as you probably expect.
I feel the answer that has been accepted is not fully correct.
Python still has overhead when importing the same module multiple times. Python handles it without giving you an error, sure, but that doesn't mean it won't slow down your script. As you will see from the URL below, there is significant overhead when importing a module multiple times.
For example, in a situation where you may not need a certain module except under a particular condition, if that module is large or has a high overhead then there is reason to import only on condition. That does not explicitly mean you are a sloppy coder either.
https://wiki.python.org/moin/PythonSpeed/PerformanceTips#Import_Statement_Overhead
from sys import modules
try:
module = modules[module_name]
except KeyError:
__import__('m')
this is my solution of changing code at runtime!

Using Pygame Module from imported script

Greetings!
I'm creating a simple snake game. I want to expand my classes in different modules e.i. have menu class in a separate script from my main game loop. In other words, I want my imported script to take the pygame init which was called earlier in main script.
Here is a quick example using pseudo code of my problem:
one.py
def version():
print pygame.version
In main.py i have imported pygame and did pygame.init(). From here, I also want to use the def version() from one.py
main.py
import pygame
import one
pygame.init()
one.version()
However, it gives me the no pygame defined error. I know the reason why it give me an error is because when the one.py is called from within the main.py, it doesnt retain the declarations from main.py.
What I want to know is a method to doing the mentioned above that will actually work.
Thank you!
The imports of the module that imports module X don't leak through to X's namespace (which is a good thing - it would either require dynamic scoping or C/C++-style #include, both are almost never useful and often even harmful). It's a completely seperate namespace on its own. If you want to use something (e.g. pygame) in a module (e.g. one), import it there.
Python's import model is the following: If you need module a.b.c in your module d.e.f, then add an import a.b.c (or similar) to the beginning of d/e/f.py. (This is similar to how Java's import works.) So if you have many modules (e.g. d.e.f1, d.e.f2, ...) which need many modules (e.g. a.b.c1, a.b.c2, ...), then you should import each required module from each of your modules, resulting multiple copies of the same import statement in your module source files. It looks like that a more compact import model (where you have to import the same module only once) would be better, but that has a very important disadvantage: the compact import model would use a global namespace, and it would make dependency tracking (e.g. who needs this code?, where does this code come from?) much harder. So every time you write an import line which you think is not necessary, remember that this is the (small) price you're paying for maintainable code.

Categories

Resources