how to import scripts as modules in ipyhon? - python

So, I've two python files:
the 1st "m12345.py"
def my():
return 'hello world'
the 2nd "1234.py":
from m12345 import *
a = m12345.my()
print(a)
On ipython I try to exec such cmds:
exec(open("f:\\temp\\m12345.py").read())
exec(open("f:\\temp\\1234.py").read())
the error for the 2nd command is:
ImportError: No module named 'm12345'
Please, help how to add the 1st file as a module for the 2nd?

First off, if you use the universal import (from m12345 import *) then you just call the my() function and not the m12345.my() or else you will get a
NameError: name 'm12345' is not defined
Secondly, you should add the following snippet in every script in which you want to have the ability of directly running it or not (when importing it).
if "__name__" = "__main__":
pass
PS. Add this to the 1st script ("m12345.py").
PS2. Avoid using the universal import method since it has the ability to mess the namespace of your script. (For that reason, it isn't considered best practice).
edit: Is the m12345.py located in the python folder (where it was installed in your hard drive)? If not, then you should add the directory it is located in the sys.path with:
import sys
sys.path.append(directory)
where directory is the string of the location where your m12345.py is located. Note that if you use Windows you should use / and not \.
However it would be much easier to just relocate the script (if it's possible).

You have to create a new module (for example m12345) by calling m12345 = imp.new_module('m12345') and then exec the python script in that module by calling exec(open('path/m12345.py').read(), m12345.__dict__). See the example below:
import imp
pyfile = open('path/m12345.py').read()
m12345 = imp.new_module('m12345')
exec(pyfile, m12345.__dict__)
If you want the module to be in system path, you can add
sys.modules['m12345'] = m12345
After this you can do
import m12345
or
from m12345 import *

Related

python go up 2 directories gives syntax error

I am making a script (python) and need to import other files (complete).
The file I would like to import, is 2 directories up from the script.
Normal in Python you would do something like
../../../file.py <-- goes up 3 directories
When I do this in Python it gives a syntax error.
..file for example works but as soon as I chain it ../..file.py the syntax error comes in.
I tried
../..file
../../file
/../..file
/../../file
The error says invalid syntax.
The complete command is
from ../..file import *
I would like to import all the content of the file.
The path needs to be relative due to the nature of the script. No hardcoding allowed.
How can I go up multiple directories in Python?
importlib was added to Python 3 to programmatically import a module.
import importlib
moduleName = input('Enter module name:')
importlib.import_module(moduleName)
The .py extension should be removed from moduleName. The function also defines a package argument for relative imports.
If you want to import the whole file you can just do import file. Then you can choose the function that you are interesting in.
for example:
import FULL_PATH_TO_MY_FILE
my_file.my_func...
or you can try:
from FULL_PATH_TO_MY_FILE import *
and then you can use each function in your file like this - myfunc()

Cannot import function from another file

I have a file called hotel_helper.py from which I want to import a function called demo1, but I am unable to import it.
My hotel_helper.py file:
def demo1():
print('\n\n trying to import this function ')
My other file:
from hotel.helpers.hotel_helper import demo1
demo1()
but I get:
ImportError: cannot import name 'demo1' from 'hotel.helpers.hotel_helper'
When I import using from hotel.helpers.hotel_helper import * instead of from hotel.helpers.hotel_helper import demo1 it works and the function gets called. I tried importing the whole file with from hotel.helpers import hotel_helper and then call the function with hotel_helper.demo1() and it works fine. I don't understand what's wrong in first method. I want to directly import function rather using * or importing the whole file.
If you filename is hotel_helper.py you have to options how to import demo1:
You can import the whole module hotel_helper as and then call your func:
import hotel_helper as hh
hh.demo1()
You can import only function demo1 from module as:
from hote_helpers import demo1
demo1()
From your fileName import your function
from hotel.helpers import demo1
demo1()
You can import a py file with the following statement:
# Other import
import os
import sys
if './hotel' not in sys.path:
sys.path.insert(0, './hotel')
from hotel import *
NOTE:
For IDE like PyCharm, you can specify the import path using the Project Structure setting tab (CTRL+ALT+S)
Helpful stack overflow questions [maybe off topic]:
What is the right way to create project structure in pycharm?
Manage import with PyCharm documentation:
https://www.jetbrains.com/help/pycharm/configuring-project-structure.html
This is probably a duplicate of: https://stackoverflow.com/posts/57944151/edit
I created two files (defdemo.py and rundefdemo.py) from your posted 2 files and substituted 'defdemo' for 'hotel.helpers.hotel_helper' in the code. My 2 files are in my script directory for Python 3.7 on windows 10 and my script directory is in the python path file python37._pth. It worked.
defdemo.py
def demo1():
print('\n\n trying to import this function ')
rundefdemo.py
from defdemo import demo1
demo1()
output
trying to import this function
I was able to solve the issue, it was related to some imports I was making in my file, when I removed all the import statement in my hotel_helper.py ,the code started working as expected , Still I don't understand reason why the issue was occurring. anyway it works.
This ImportError can also arise when the function being imported is already defined somewhere else in the main script (i.e. calling script) or notebook, or when it is defined in a separate dependency (i.e. another module). This happens most often during development, when the developer forgets to comment out or delete the function definition in the body of a main file or nb after moving it to a module.
Make sure there are no other versions of the function in your development environment and dependencies.

How do I import from a file in the current directory in Python 3?

In python 2 I can create a module like this:
parent
->module
->__init__.py (init calls 'from file import ClassName')
file.py
->class ClassName(obj)
And this works. In python 3 I can do the same thing from the command interpreter and it works (edit: This worked because I was in the same directory running the interpreter). However if I create __ init __.py and do the same thing like this:
"""__init__.py"""
from file import ClassName
"""file.py"""
class ClassName(object): ...etc etc
I get ImportError: cannot import name 'ClassName', it doesn't see 'file' at all. It will do this as soon as I import the module even though I can import everything by referencing it directly (which I don't want to do as it's completely inconsistent with the rest of our codebase). What gives?
In python 3 all imports are absolute unless a relative path is given to perform the import from. You will either need to use an absolute or relative import.
Absolute import:
from parent.file import ClassName
Relative import:
from . file import ClassName
# look for the module file in same directory as the current module
Try import it this way:
from .file import ClassName
See here more info on "Guido's decision" on imports in python 3 and complete example on how to import in python 3.

How can I import a python file through a command prompt?

I am working on project euler and wanted to time all of my code. What I have is directory of files in the form 'problemxxx.py' where xxx is the problem number. Each of these files has a main() function that returns the answer. So I have created a file called run.py, located in the same directory as the problem files. I am able to get the name of the file through command prompt. But when I try to import the problem file, I continue to get ImportError: No module named problem. Below is the code for run.py so far, along with the command prompt used.
# run.py
import sys
problem = sys.argv[1]
import problem # I have also tired 'from problem import main' w/ same result
# will add timeit functions later, but trying to get this to run first
problem.main()
The command prompts that I have tried are the following: (both of which give the ImportError stated above)
python run.py problem001
python run.py problem001.py
How can I import the function main() from the file problem001.py? Does importing not work with the file name stored as a variable? Is there a better solution than trying to get the file name through command prompt? Let me know if I need to add more information, and thank you for any help!
You can do this by using the __import__() function.
# run.py
import sys
problem = __import__(sys.argv[1], fromlist=["main"]) # I have also tired 'from problem import main' w/ same result
problem.main()
Then if you have problem001.py like this:
def main():
print "In sub_main"
Calling python run.py problem001 prints:
In sub_main
A cleaner way to do this (instead of the __import__ way) is to use the importlib module. Your run.py needs to changes:
import importlib
problem = importlib.import_module(sys.argv[1])
Alternatives are mentioned in this question.
For sure! You can use __ import_ built-in function like __import__(problem). However this is not recommended to use, because it is not nice in terms of coding-style. I think if you are using this for testing purposes then you should use unittest module, either way try to avoid these constructions.
Regards
You can use exec() trick:
import sys
problem = sys.argv[1]
exec('import %s' % problem)
exec('%s.main()' % problem)

Python - Importing a global/site-packages module rather than the file of the same name in the local directory

I'm using python and virtualenv/pip. I have a module installed via pip called test_utils (it's django-test-utils). Inside one of my django apps, I want to import that module. However I also have another file test_utils.py in the same directory. If I go import test_utils, then it will import this local file.
Is it possible to make python use a non-local / non-relative / global import? I suppose I can just rename my test_utils.py, but I'm curious.
You can switch the search order by changing sys.path:
del sys.path[0]
sys.path.append('')
This puts the current directory after the system search path, so local files won't shadow standard modules.
My problem was even more elaborate:
importing a global/site-packages module from a file with the same name
Working on aero the pm recycler I wanted access to the pip api, in particular pip.commands.search.SearchCommand from my adapter class Pip in source file pip.py.
In this case trying to modify sys.path is useless, I even went as far as wiping sys.path completely and adding the folder .../site-packages/pip...egg/ as the only item in sys.path and no luck.
I would still get:
print pip.__package__
# 'aero.adapters'
I found two options that did eventually work for me, they should work equally well for you:
using __builtin__.__import__() the built-in function
global_pip = __import__('pip.commands.search', {}, {}, ['SearchCommand'], -1)
SearchCommand = global_pip.SearchCommand
Reading the documentation though, suggests using the following method instead.
using importlib.import_module() the __import__ conv wrapper.
The documentation explains that import_module() is a minor subset of functionality from Python 3.1 to help ease transitioning from 2.7 to 3.1
from importlib import import_module
SearchCommand = import_module('pip.commands.search').SearchCommand
Both options get the job done while import_module() definitely feels more Pythonic if you ask me, would you agree?
nJoy!
I was able to force python to import the global one with
from __future__ import absolute_import
at the beginning of the file (this is the default in python 3.0)
You could reset your sys.path:
import sys
first = sys.path[0]
sys.path = sys.path[1:]
import test_utils
sys.path = first + sys.path
The first entry of sys.path is "always" (as in "per default": See python docs) the current directory, so if you remove it you will do a global import.
Since my test_utils was in a django project, I was able to go from ..test_utils import ... to import the global one.
Though, in first place, I would always consider keeping the name of local file not matching with any global module name, an easy workaround, without modifying 'sys.path' can be to include global module in some other file and then import this global module from that file.
Remember, this file must be in some other folder then in the folder where file with name matching with global module is.
For example.
./project/root/workarounds/global_imports.py
import test_utils as tutil
and then in
./project/root/mycode/test_utils.py
from project.root.workarounds.global_imports import tutil
# tutil is global test_utils
# you can also do
from project.root.workarounds.global_imports import test_utils

Categories

Resources