using __import__() function in my function in python - python

thank you all, this problem was solved
but I don't know What is the different between them
wrong script :
def func(module) :
cwd = os.getcwd()
os.chdir(module['path'])
tmp = __import__(module['name'])
os.chdir(cwd)
working well script :
def func(module) :
sys.path.append(module['path'])
tmp = __import__(module['name'])
...
happy new year :)
============================================================
Hello I need to import dynamically in python script
when I try __import__() outside of a function
ex)
__import__('myModule')
it does work, but when I try it within a function
ex )
def func() :
__import__('myModule')
func()
I get an ImportError: ImportError: No module named myModule
How can I use __import__() in function??

I think what you want to use here is the following:
from importlib import import_module
def func():
import_module('myModule')

When Python starts, the script’s directory is put at the front of sys.path, so that import finds things in it. In some cases (not, for example, python foo/bar.py), what is put there is an empty string, which means “search the current working directory”. Only in that case will os.chdir affect import in the way you expected.

Related

Python: NameError when trying to use "re" inside a function

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.

Python: After initialising a module, no longer can import functions

I have two files: 'my_main.py' and 'my_functions.py'. I wrote two functions in 'my_functions.py', 'first_function' and 'second_function' and imported this module into 'my_main.py'. However, I then added a third function into 'my_functions.py' called 'third_function':
def first_function():
print("hello1")
def second_function():
print("hello2")
def third_function():
print("hello3")
I found that I could not import 'third_function' into 'my_main.py', getting an error - AttributeError: module 'my_functions' has no attribute 'third_function'.
To understand this, in 'my_main.py' I then ran:
import my_functions
help(my_functions)
and had as my output:
Help on module my_functions:
NAME
my_functions
FUNCTIONS
first_function()
second_function()
For some reason 'my_functions.py' would not recognise any more functions after the initial two, meaning I couldn't then import 'third_function' into 'my_main.py'. How can I fix this?
Make sure you have saved your file my_functions.py before running my_main.py. Unless the file is saved, the update (addition of third_function) won't be recognized. Have been doing this for years, and still make this mistake constantly. Editing not enough. Need to edit and save.
You need to explicitly reload the module if you've made changes since the last import. There is a built-in function for this
You can reload your module as follows:
import importlib
importlib.reload(my_functions)
See this answer for a much more detailed explanation.

Python relative __import__

Suppose I have a module package containing the following files. An empty file C:\codes\package\__init__.py and some non-trivial files:
One located in C:\codes\package\first.py
def f():
print 'a'
Another located in C:\codes\package\second.py
def f():
print 'b'
There is also a third file: C:\codes\package\general.py with the following code
def myPrint(module_name):
module = __import__(module_name)
module.f()
if __name__ == '__main__':
myPrint('first')
myPrint('second')
When I run the latter file, everything goes fine. However, if I try to execute the file C:\codes\test.py containing
if __name__ == '__main__':
from package import general
general.myPrint('first')
general.myPrint('second')
I get the import error ImportError: No module named first. How to resolve this issue?
First, I suspect you forgot to metion you have a (possibly empty) file package\__init__.py which makes package a package. Otherwise, from package import general wouldn't work.
The second case differs from the first in so far as you are in a package. From inside a package, you wouldn't do import first, but import .first. The equivalent to the latter is described here where you either add level=1 as a parameter or (but I am not sure about that) you put .first into the string and set level to -1 (if it isn't the default nevertheless, that's not clear from the documentation).
Additionally, you have to provide at least globals(), so the right line is
module = __import__(module_name, globals(), level=1)
I have found this solution here.
In your case, you should import your module_name from package. Use fromlist argument:
getattr(__import__("package", fromlist=[module_name]), module_name)
Assuming, you're using Python 3, that's just because this version dropped the support for implicit relative imports. With Python 2 it would be working just fine.
So either you'd need to use relative imports in C:\codes\package\general.py, which would result in erroneous call to it, or add your package to the path. A little dirty, but working hack would be:
def myPrint(module_name):
pkg = os.path.dirname(__file__)
sys.path.insert(0, pkg)
try:
module = __import__(module_name)
except:
raise
finally:
sys.path.remove(pkg)
module.f()
Maybe you can achieve a cleaner implementation with the importlib module.

Is it possible to get "importing module" in "imported module" in Python?

For imported module, is it possible to get the importing module (name)? I'm wondering if inspect can achieve it or not~
It sounds like you solved your own problem: use the inspect module. I'd traverse up the stack until I found a frame where the current function was not __import__. But I bet if you told people why you want to do this, they'd tell you not to.
Even if you got it to work, this is probably less useful than you think since subsequent imports only copy the existing reference instead of executing the module again.
foo.py:
import bar
bar.py:
import traceback
try:
filename,line_number,function_name,text = traceback.extract_stack()[-2]
print(filename,line_number,function_name,text)
except IndexError:
pass
Running foo.py yields something like
('/home/unutbu/pybin/foo.py', 4, '<module>', 'import bar')
import inspect
result = filter(lambda v:inspect.ismodule(v), globals().values())
#result is a collection of all imported modules in the file, the name of any of which can be easily got by .__name__
#replace globals() with inspect.getmembers(wanted_module) if you want the result outside the wanted module

how to run python script from shell

I have a noob question.
I got a python script path1/path2/file.py
The script has a function:
def run (datetime = None):
In the shell I call
import path1.path2.file
import datetime
path1.path2.file.run(datetime = datetime(2011,12,1))
but I am getting
TypeError: 'module' object is not callable
whats the correct way to call the method in the shell?
The problem is actually in the datetime module.
You are trying to call the module itself.
The function you want to call is itself called datetime.
so what you want to call is:
datetime.datetime()
OR you can import the function with:
from datetime import datetime
and then call it with:
datetime()
You can write:
import path1
path1.path2.file.run(...)
Or:
from path1.path2.file import run
run(...)
Don't forget that you need an __init__.py file in each directory (path1 and path2) to make the directory as a module (and then, allow it to be importable.). That file can just be empty if you have nothing to put in it.
Try the following:
from path1.path2.file import run
If none of these work, here is a (a little bit dirty) way of doing it:
# Python <= 2.7
namespace = {}
exec open("path1/path2/file.py").read() in namespace
namespace["run"](datetime=datetime.datetime(2011,12,1))
or
# Python >= 3.0
namespace = {}
exec(open("path1/path2/file.py").read(), namespace)
namespace["run"](datetime=datetime.datetime(2011,12,1))
Of course you could omit the namespace = {} and the in namespace / , namespace parts, but then, the code in file.py might actually change other variables in your shell.
you can import a folder doing
import path1
and then call simply the script doing:
path1.path2.file.run(...)
otherwhise if you do not want to include all the other stuff within the directory you can try with
from path1.path2.file import run
in this case you have only to call:
run()
Cheers,

Categories