Using Pygame Module from imported script - python

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.

Related

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.

Why must I import before I can call a module

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

Shared import in Python [duplicate]

If I were to create a module that was called for example imp_mod.py and inside it contained all (subjectively used) relevant modules that I frequently used.
Would importing this module into my main program allow me access to the imports contained inside imp_mod.py?
If so, what disadvantages would this bring?
I guess a major advantage would be a reduction of time spent importing even though its only a couple of seconds saved...
Yes, it would allow you to access them. If you place these imports in imp_mod.py:
from os import listdir
from collections import defaultdict
from copy import deepcopy
Then, you could do this in another file, say, myfile.py:
import imp_mod
imp_mod.listdir
imp_mod.defaultdict
imp_mod.deepcopy
You're wrong about reduction of importing time, as what happens is the opposite. Python will need to import imp_mod and then import the other modules afterwards, while the first import would not be needed if you were importing these modules in myfile.py itself. If you do the same imports in another file, they will already be in cache, so virtually no time is spent in the next import.
The real disadvantage here is less readability. Whoever looks at imp_mod.listdir, for example, will ask himself what the heck is this method and why it has the same name as that os module's method. When he had to open imp_mod.py just to find out that it's the same method, well, he probably wouldn't be happy. I wouldn't.
As lucasnadalutti mentioned, you can access them by importing your module.
In terms of advantages, it can make your main program care less about where the imports are coming from if the imp_mod handles all imports, however, as your program gets more complex and starts to include more namespaces, this approach can get more messy. You can start to handle a bit of this by using __init__.py within directories to handle imports to do a similar thing, but as things get more complex, personally, I feel it add a little more complexity. I'd rather just know where a module came from to look it up.

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!

Categories

Resources