This question already has an answer here:
Why Python print my output two times when I import the same file in which I am printing?
(1 answer)
Closed 2 years ago.
Here is the code
import random
print("Hello", end="")
print("twice")
and a screenshot of the code
When I execute this code it for some reason is running twice. The problem seems to be from the import random statement, because if I either remove that statement or import some other module it works fine.
What could be the reason for this, should I reinstall Python on my system.
There's nothing wrong with python.
The reason is simple:
Your module is importing itself (because it is also named random) - this has to do with the lookup mechanics of python. python will try to import from your root folder first, before modules from pythonpath are imported.
From the docs:
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
The directory containing the input script (or the current directory
when no file is specified).
PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
The installation-dependent default.
Since your file (module) is called random.py, import random will import this very file.
Now, what does "import" mean?
The statement import something will cause Python to lookup the name something, starting with the current directory.
Therefore, import random will result in an import of this very file, since its name will shadow the build-in random.
Besides, if the name to import is already in the namespace, then the import statement is ignored.
Once the module to import has been located, its code is executed.
As a result, the flow of your script is as follow:
Lookup the random.py name
Add random to the namespace
Execute the code contained in random.py
The random name already exists in the namespace, so the import random statement is ignored
Print the text
Print the text
The reason for this is you've named the script random.py and inside it you import random.
random will not import the built-in random module but, rather, the random module you've created. This leads to the script executing the same statements twice (and also leads to other ugly errors if you tried and import something from random, like from random import randrange.)
Renaming the script leads to normal behavior.
Because your scripts is called random.py, so when you import random you are executing your script as well. Mind to name correctly your scripts.
your python script is named random.py so when you import random it import itself , in python when you import module it will run it.
therefor you get print twice.
rename your script or remove the import
Related
My question is very simple. I have a piece of code that I want to reuse, but I don't want to copy it every time I use it. Is there any way I can import it and run it in my main file?
For example, in file code1.py:
a=1
I want to run in code2.py:
import code1
b=a+1
print(b)
The output says a is not defined. I don't know where I got it wrong. I am a beginner in Python, so this will help me a lot in the future, thanks.
Ensure that the two files are in the same directory.
If this is the case, you can directly import
from filename import variablename/class/function
in your case:
from code1 import a
This lesson is good to understand imports in python: https://realpython.com/python-import/
You will need to import the variable from the your Python module to use it.
from code1 import a
The import statement will differ slightly if your modules are not at the same level.
The code showed below is based on the fact that files code1.py and code2.py are in the same directory.
Solution 1
In this code I have changed only your import instruction in code2.py:
from code1 import a
b = a + 1
print(b)
Solution 2
In this solution I don't have changed your import instruction in the file code2.py, but I have used the module name (code1) to refer to a variable. In this case it is used the access notation moduleName.variableName.
So the file code2.py becomes:
import code1
b = code1.a + 1
print(b)
This means that in this case code1.py is used as a Python module and not as a script (the difference between script and module could be the topic of an other question).
Python namespace
In Python terminology the moduleName is the namespace defined by the module. By the namespace (that is the name placed after the import instruction) you can access to the objects content inside the module by the syntax namespace.object.
The interpreter creates a global namespace for any module that your program loads with the import statement.
About namespace useful this link of realpython.
I have a script called main_plotter.py that looks like this:
import re
import numbs
numbs.getSquares("file.csv")
numbs.py is the file that I'm importing from. It looks like this:
def getSquares(sqfile):
infile=sqfile
base_name = re.split(".csv", infile)[0]
print (base_name)
When I run main_plotter.py, I get NameError: name 're' is not defined.
Why is this happening? I tried adding global re before the import re statement, but that doesn't help either. Aren't the import statements supposed to be global anyway? Any help appreciated!
PS. the code runs as expected if I import re inside the numbs.py file.
"Global" in Python means "module namespace". Any import re happens exactly there -- module-by-module; there intentionally does not exist any wider scope, which ensures that the content of any Python module can be understood by reading only that module (unlike Ruby, where to know the context in which code is run you need to read every module that was ever loaded by the same interpreter).
If you want to use the re module in numbs.py, you should have a separate import re inside that file. This doesn't reload the module from disk, but just adds a namespace entry pointing to the already-cached instance that was loaded on first reference.
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.
Could someone please shed some light on this behavior in the Python interpreter:
from os import path # success
type(path) # <class 'module'>
from path import * # complains that no module called 'path' exists
type(os.path) # complains that the name 'os' is not defined, yet:
from os.path import * # works just fine
As a side-question, I wonder what is the mechanism that allows a statement such as 'from os import path' to work, while yet still os is undefined? Isn't os executed at the time of the from...import, and such it should be "known" as a module? Am I right to say that keeping os out of the known names is simply a convention, intended to prevent the "polution" of the namespace with symbols that have not been imported directly (as in 'import os')?
This is not specific to Python 3, you'd have the same problem in Python 2. Importing of a name adds it to the namespace, nothing more.
This line:
from path import *
Means:
"Try to find a module called path in any directory that is in
PYTHONPATH, and attempt to import all names from it to the current
namespace."
Since there is no such module in the current working directory, and more importantly not in any directory that's in PYTHONPATH, the import fails. Note, the search doesn't search the sub directories of any directory that is in PYTHONPATH.
type(os.path)
This line fails because there is no name os in the current namespace (since its not imported).
I wonder what is the mechanism that allows a statement such as 'from
os import path' to work, while yet still os is undefined?
Importing causes a search of paths that are defined in PYTHONPATH to be searched for modules; see this article on effbot for more clarification on how importing works.
"Undefined" simply means the name doesn't exist in the namespace.
Isn't os executed at the time of the from...import, and such it should
be "known" as a module?
No, when you do from x import y only y is imported, not x.
Am I right to say that keeping os out of the known names is simply a
convention, intended to prevent the "polution" of the namespace with
symbols that have not been imported directly (as in 'import os')?
No, this is not true (and I hope you understand why).
I understand how to actually link python files, however, i don't understand how to get variable's from these linked files. I've tried to grab them and I keep getting NameError.
How do I go about doing this? The reason i want to link files is to simply neaten up my script and not make it 10000000000 lines long. Also, in the imported python script, do i have to import everything again? Another question, do i use the self function when using another scripts functions?
ie;
Main Script:
import sys, os
import importedpyfile
Imported Py File
import sys, os
I understand how to actually link python files, however, i don't
understand how to get variable's from these linked files. I've tried
to grab them and I keep getting NameError.
How are you doing that? Post more code. For instance, the following works:
file1.py
#!/usr/bin/env python
from file2 import file2_func, file2_variable
file2_func()
print file2_variable
file2.py:
#!/usr/bin/env python
file2_variable = "I'm a variable!"
def file2_func():
print "Hello World!"
Also, in the imported python script, do i have to import everything
again?
Nope, modules should be imported when the python interpreter reads that file.
Another question, do i use the self function when using another
scripts functions?
Nope, that's usually to access class members. See python self explained.
There is also more than one way to import files. See the other answer for some explanations.
I think what you are trying to ask is how to get access to global vars from on .py file without having to deal with namespaces.
In your main script, replace the call to import importedpyfile to say this instead
from importedpyfile import *
Ideally, you keep the code the way you have it. But instead, just reference those global vars with the importedpyfile namespace.
e.g.
import importedpyfile
importedpyfile.MyFunction() # calls "MyFunction" that is defined in importedpyfile.py
Python modules are not "linked" in the sense of C/C++ linking libraries into an executable. A Python import operation creates a name that refers to the imported module; without this name there is no (direct) way to access another module.