Python file does not recognize imported functions from other Python files - python

I'm trying to make my code more organized by creating separate files for various functions. I'm testing out printing scenes of dialogue with a text scrolling code, and instead of keeping every line of dialogue in one file, I have moved it to a scene0.py file in the folder scenes. In that file, I define the function playscene0.
In a different folder called scenetext, I have a file called textstuff.py which contains the defined functions print_italics (which prints italics text), texttype (which makes each character type out individually like some video games do), and textscroll (which reads lists of dialog and formats it, plus timings with time.sleep).
That aforementioned scene0.py file uses from scenetext.textstuff import * to import the above functions, plus additional variables that go along with them (unique to that file). VSCode seems to initially recognize that all the functions being used in the playscene0 function have been successfully imported.
In my importtest file:
from scenes.scene0 import playscene0
playscene0()
This gives me:
NameError: name 'print_italics' is not defined
Though it very much is defined in the file it is derived from.
I've already looked into circular imports and how they cause problems, but that doesn't seem to be the cause here. I've tried importing both time and everything from scenetext.textstuff in the importtest file directly, but the problem persists.
Any suggestions are welcome, thank you
EDIT: After adding from scenetext.textstuff import print_italics to the importtest file, it gives me a different error upon running:
ImportError: cannot import name 'print_italics' from 'scenetext.textstuff' (/Users/[me]/vscode/VOYAGE/scenetext/textstuff.py)
Not sure what causes this.

You need to add an import to the importtest file - from scenetext.textstuff import print_italics, so that the function becomes "visible".

You should import the textstuff functions BEFORE you import the playscene function that uses them
from scenetect.textstuff import print_italics
from scenes.scene0 import playscene0
playscene0()

Related

Python not able to import module

I have quite a number of different file which I want to use to create an API. The files are :
app.py -- main file
utils.py -- utilities file
recorder.py
consts.py
submitter.py
All of these files have a dependency on one another. However, when I try to import them in a particular file ( for ex - importing consts in recorder.py, I am getting error saying The module consts is not found.
I am importing it using :
from .consts import consts
Can someone tell me what am I doing wrong here, and how to solve this issue.
If i import it in the main app.py, it doesn't give any error. but it does when I want to access any consts in other files.
Thank you in advance
EDIT : Here is the folder structure :
When you say they are interdependent, that may be your issue. You cannot have two files that depend directly on one another with out some hacky solutions as youll run into the problem of importing one that tries to import the importer which tries to import the importee and so on forever.
Edit: i misunderstood how imports work, the problem comes from:
"If you import X from your main program, Python will load the code for
X and execute it. When Python reaches the import Y statement, it loads
the code for Y, and starts executing it instead.
At this time, Python has installed module objects for both X and Y in
sys.modules. But X doesn’t contain anything yet; the def spam
statement hasn’t been executed."
As stated in the link i included at the bottom of this response. The link also gives some possible solutions like changing when you import the different modules.
What we really need is to see the code for the files to understand how you are importing everything
this link should help you in your desire for circular dependency.

Taking an input from python file to another

I made a file that turns to other files and run their scripts consecutively. Most of these files have a common parameter which is an input. When I import it, it (of course) requests for input. I wish to avoid re-input of something.
Example:
MainFile.py:
import Base_params
import Liner
Base_params.py:
no_of_slices=int(input('Enter no. of Slices'))
sub_slice=int(input('enter sub slice'))
Liner.py:
from PIL import Image
import shutil
from Base_params import no_of_slices, sub_slice
The short answer is that Python handles this for you already exactly the way you want. To understand why, let me give you a little background on the import system.
When a module is imported for the first time, an empty module object is created. Then its code is executed and any names you bind are placed in its dictionary, which is also the global namespace for the module. In your case that would mean running the code of Base_params.py and creating the names no_of_slices and sub_slice based on the user input.
When the same module is imported subsequently, its code is not run (which is your concern). Instead, the object reference from sys.modules is returned. An import statement always checks whether a module is already loaded before attempting to run it again.
The reason that creating the empty module object (and placing it in sys.modules before running the module code is very important is that most modules have recursive imports. Marking the module as already imported ensures that any infinite loops are broken before they happen.
In your case, it is perfectly fine to define a module of constants that asks for user input. The first module that does import Base_params will trigger an execution of the input statements. All further occurrences of import Base_params will just bind sys.modules['Base_params'] to whatever the name Base_params in your namespace. There will not be a second query for no_of_slices and sub_slice.
The links to the official documentation I provided throughout will explain anything I missed.

Whitch is better: import every thing into every file or import everything from an other file

I want to know which way the best is for importing modules.
I'm currently using multiple files for my Pygame-Game. There are the main files and there is also a file where I import everything from.
It's like this:
settings.py:
import pygame,random,os,...
a main game file:
from settings import pygame
Everything works fine but should I do it instead like this?
a main game file(rewriten):
import pygame
The first way to import modules implies that there's a reason you import pygame from settings and not directly.
You might have modified some variables, functions or objects from pygame in settings.py, so that the stuff imported from settings.pygame has different behavior than that imported from pygame directly.
Just for the sake of an example (of how not to do it I'd say):
Say your pygame.py has a function like:
enemy_action( In_1, ... , In_n, DIFFICULTY )
In your settings.py you now probably have the difficulty setting stored, so you could redefine the function with DIFFICULTY already set by creating a decorator for the function:
pygame.DIFFICULTY = DIFFICULTY
def pygame.difficulty_setter(f):
def inner(*x, DIFFICULTY = pygame.DIFFICULTY):
return f(*x,DIFFICULTY = pygame.DIFFICULTY)
return inner
If you now set
enemy_action = pygame.difficulty_setter(enemy_action)
The function enemy_action wouldn't need to be passed the DIFFICULTY parameter anymore.
As the link bellow said, import necessary modules in another module, is a good shape looking code. For large projects it is a necessary work, because every thing going to be crazy.
Python import modules in another file

Is it possible to run imported code as a part of the main file?

The question is pretty simple: I need to move a piece of my code to the another file. In the main file, I'll do something like import not_main. Is is possible to run imported code as a part of the main file? Here's a simplified example:
__code
\__main.py
|__not_main.py
main.py content:
a = 5
import not_main
not_main.py content:
print a
When I'm running main.py, there is a error : NameError: name 'a' is not defined. How can I make it work? Thanks for any tips.
It's not possible to directly reference a variable in one module that's defined in another module unless you import that module first. Doesn't matter that it's the main module, this error would happen if you tried to do the same between any two modules. An imported module does not gain the scope of the module it's imported into.
There are possible workarounds, though I would caution using them if the code you're trying to separate out is fairly complex. But if you're intent on doing it, I'd suggest separating out any variables needed in both modules into a third module that only contains those variables. So the simple example you gave would turn into this:
cross_module_variables.py:
a = 5
main.py:
import not_main
not_main.py:
import cross_module_variables as cmv
print cmv.a
For more complex code you might need to assign the value of the variable in main after doing executing some code to produce the value. In that case you'll want to import cross_module_variables into the main module and assign a value to it. Course that variable has to be instantiated before it can be used in main so you'll have define the variable in cross_module_variable with some default value. So it would look something more like this:
cross_module_variables.py:
a = 0
main.py:
import cross_module_variables as cmv
cmv.a = 5
import not_main
not_main.py:
import cross_module_variables as cmv
print cmv.a
See this answer for more info on cross module variables.
With all that said, I would highly suggest you look at restructuring your code in some other sane way. It sounds like you're running all your code straight in modules instead of defining functions around discrete sections of code. You should look into ways of designing coherent functional programs.

python module import syntax

I'm teaching myself Python (I have experience in other languages).
I found a way to import a "module". In PHP, this would just be named an include file. But I guess Python names it a module. I'm looking for a simple, best-practices approach. I can get fancy later. But right now, I'm trying to keep it simple while not developing bad habits. Here is what I did:
I created a blank file named __init__.py, which I stored in Documents (the folder on the Mac)
I created a file named myModuleFile.py, which I stored in Documents
In myModuleFile.py, I created a function:
def myFunction()
print("hello world")
I created another file: myMainFile.py, which I stored in Documents
In this file, I typed the following:
import myModuleFile.py
myModuleFile.myFunction()
This successfully printed out "hello world" to the console when I ran it on the terminal.
Is this a best-practices way to do this for my simple current workflow?
I'm not sure the dot notation means I'm onto something good or something bad. It throws an error if I try to use myFunction() instead of myModuleFile.myFunction(). I kind of think it would be good. If there were a second imported module, it would know to call myFunction() from myModuleFile rather than the other one. So the dot notation makes everybody know exactly which file you are trying to call the function from.
I think there is some advanced stuff using sys or some sort of exotic configuration stuff. But I'm hoping my simple little way of doing things is ok for now.
Thanks for any clarification on this.
For your import you don't need the ".py" extension
You can use:
import myModuleFile
myModuleFile.myFunction()
Or
from myModuleFile import myFunction
myFunction()
Last syntax is common if you import several functions or globals of your module.
Besides to use the "main" function, I'd put this on your module:
from myModuleFile import myFunction
if __name__ == '__main__':
myFunction()
Otherwise the main code could be executed in imports or other cases.
I'd use just one module for myModuleFile.py and myMainFile.py, using the previous pattern let you know if your module is called from command line or as import.
Lastly, I'd change the name of your files to avoid the CamelCase, that is, I'd replace myModuleFile.py by my_module.py. Python loves the lowercase ;-)
You only need to have init.py if you are creating a package (a package in a simple sense is a subdirectory which has one or more modules in it, but I think it may be more complex than you need right now).
If you have just one folder which has MyModule.py and MyMainFile.py - you don't need the init.py.
In MyMainFile.py you can write :
import myModuleFile
and then use
myModuleFile.MyFunction()
The reason for including the module name is that you may reuse the same function name in more than one module and you need a way of saying which module your program is using.
Module Aliases
If you want to you can do this :
import myModuleFile as MyM
and then use
MyM.MyFunction()
Here you have created MyM as an alias for myModuleFile, and created less typing.
Here Lies Dragons
You will sometimes see one other forms of IMport, which can be dangerous, especially for the beginner.
from myModuleFile import MyFunction
if you do this you can use :
MyFunction()
but this has a problem if you have used the same function name in MyMainFile, or in any other library you have used, as you now can't get to any other definition of the name MyFunction. This is often termed Contaminating the namespace - and should really be avoided unless you are absolutely certain it is safe.
there is a final form which I will show for completeness :
from myModuleFile import *
While you will now be able to access every function defined in myModuleFile without using myModuleFile in front of it, you have also now prevented your MyMainFile from using any function in any library which matches any name defined in myModuleFile.
Using this form is generally not considered to be a good idea.
I hope this helps.

Categories