I am having an import problem. What I am trying to do is to import 2 functions with the same name from modules with the same name. Note that i am doing this in Pycharm.
I have the following directory structure:
test_import
|--foo.py
|--main.py
|--test
|--foo.py
Code
foo.py in the test_import folder looks like:
def print_arg(x):
print('print 1: {}'.format(x))
foo.py in the test folder looks like:
def print_arg(x):
print('print 2: {}'.format(x))
Here is my code in main.py in which I am doing the imports of print_arg:
import sys
from foo import print_arg as print_arg
print_arg(1)
sys.path.insert(1, './test')
from foo import print_arg as print_arg_2
print_arg(1)
print_arg_2(1)
I expect this to print
print 1: 1
print 1: 1
print 2: 1
But it prints
print 1: 1
print 1: 1
print 1: 1
Somehow the second import does not work and print_arg_2 becomes a reference to print_arg. This is illustrated by doing the imports the other way around:
sys.path.insert(1, './test')
from foo import print_arg as print_arg_2
print_arg_2(1)
sys.path.pop(1)
from foo import print_arg
print_arg(1)
print_arg(1)
print_arg_2(1)
which prints:
print 2: 1
print 2: 1
print 2: 1
Changing the function name in test/foo.py to print_arg_2 does not work, it results in an error. It seems like a reference to foo.py in the project folder has been created and it tries to import from there instead of looking in other directories on sys.path
Traceback (most recent call last):
File "C:\Users\jeroe\AppData\Local\Programs\Python\Python37\lib\site-packages\IPython\core\interactiveshell.py", line 3326, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-2-10fe80aec78f>", line 5, in <module>
from foo import print_arg_2 as print_arg_2
ImportError: cannot import name 'print_arg_2' from 'foo' (C:\Users\jeroe\PycharmProjects\test_import\foo.py)
Changing the filename of foo.py in the test folder to e.g. foo2.py does work. However I prefer not to change the filename.
So I have 2 questions:
Can somebody explain me what is going on here?
What is a better way to import these 2 functions without having to change the file (module) name?
First of all, you have to add an empty __init__.py file inside the test folder, so the second foo file can be imported.
Secondly, you have to write the full relative path to the second file when importing it. Right now, you are importing both times the first foo file.
Just modify the second import line to:
from test.foo import print_arg as print_arg_2
I am relatively new to python, and I am struggling to find a combination of file hierarchy and import statements that will work in pycharm, pytest on the command line, running the actual program on the command line, and building in bamboo.
Here is my hierarchy:
foo
| goo
| __init__.py
| run.py
| koo
| __init__.py
| bar.py
| loo
| __init__.py
| baz.py
| tests
| __init__.py
| test_bar.py
| test_baz.py
| test_file.py
| data
| text.txt
Here is my code:
foo/goo/koo/bar.py:
greeting = "hello"
def hello():
return greeting
foo/goo/loo/baz.py:
from koo import bar
def greet():
return "the greeting is..." + bar.hello()
foo/goo/run.py:
import loo.baz as baz
print(baz.greet())
foo/tests/test_bar.py:
import goo.koo.bar as b
def test_hello():
assert b.hello() == "hello"
foo/tests/test_baz.py:
import goo.loo.baz as b
def test_greet():
assert b.greet() == "the greeting is...hello"
foo/tests/test_file.py:
import os.path
import sys
def test_file():
f = open(os.path.join(sys.path[0], "tests", "data", "test.txt"), "rt")
assert f.read() == "hello world"
When I go to the foo directory and run
python goo/run.py
this works. But when I run
python -m pytest tests
I get the error
Traceback:
tests/test_baz.py:1: in <module>
import goo.loo.baz as b
goo/loo/baz.py:1: in <module>
from koo import bar
E ModuleNotFoundError: No module named 'koo'
If I change baz.py to the following:
from goo.koo import bar
def greet():
return "the greeting is..." + bar.hello()
then all the tests pass, but running the program gives this error:
Traceback (most recent call last):
File "goo/run.py", line 1, in <module>
import loo.baz as baz
File "/home/me/PycharmProjects/foo/goo/loo/baz.py", line 1, in <module>
from goo.koo import bar
ModuleNotFoundError: No module named 'goo'
This question is similar, but does not have a marked answer. One posted answer suggests moving the tests folder down, but this caused an issue on our build server, and also the common practice here seems to be to have the tests at the top level.
Assuming I want to keep the tests at the top level, is there any combination of imports that will work?
I would use a combination of absolute imports e.g. from goo.koo import bar and adding the folder foo to your PYTHONPATH with
export PYTHONPATH=$PYTHONPATH:/path/to/foo
then structuring all your imports as if they are originating from the foo folder
Im pretty new to python, and have been having a rough time learning it. I have a main file
import Tests
from Tests import CashAMDSale
CashAMDSale.AMDSale()
and CashAMDSale
import pyodbc
import DataFunctions
import automa
from DataFunctions import *
from automa.api import *
def AMDSale():
AMDInstance = DataFunctions.GetValidAMD()
And here is GetValidAMD
import pyodbc
def ValidAMD(GetValidAMD):
(short method talking to a database)
My error comes up on the line that has AMDInstance = DataFunctions.GetValidAMD()
I get the error AttributeError: 'module' object has no attribute 'GetValidAMD'
I have looked and looked for an answer, and nothing has worked. Any ideas? Thanks!
DataFunctions is a folder, which means it is a package and must contain an __init__.py file for python to recognise it as such.
when you import * from a package, you do not automatically import all it's modules. This is documented in the docs
so for your code to work, you either need to explicitly import the modules you need:
import DataFunctions.GetValidAMD
or you need to add the following to the __init__.py of DataFunctions:
__all__ = ["GetValidAMD"]
then you can import * from the package and everything listen in __all__ will be imported
When you create the file foo.py, you create a python module. When you do import foo, Python evaluates that file and places any variables, functions and classes it defines into a module object, which it assigns to the name foo.
# foo.py
x = 1
def foo():
print 'foo'
>>> import foo
>>> type(foo)
<type 'module'>
>>> foo.x
1
>>> foo.foo()
foo
When you create the directory bar with an __init__.py file, you create a python package. When you do import bar, Python evaluates the __init__.py file and places any variables, functions and classes it defines into a module object, which it assigns to the name bar.
# bar/__init__.py
y = 2
def bar():
print 'bar'
>>> import bar
>>> type(bar)
<type 'module'>
>>> bar.y
2
>>> bar.bar()
bar
When you create python modules inside a python package (that is, files ending with .py inside directory containing __init__.py), you must import these modules via this package:
>>> # place foo.py in bar/
>>> import foo
Traceback (most recent call last):
...
ImportError: No module named foo
>>> import bar.foo
>>> bar.foo.x
1
>>> bar.foo.foo()
foo
Now, assuming your project structure is:
main.py
DataFunctions/
__init__.py
CashAMDSale.py
def AMDSale(): ...
GetValidAMD.py
def ValidAMD(GetValidAMD): ...
your main script can import DataFunctions.CashAMDSale and use DataFunctions.CashAMDSale.AMDSale(), and import DataFunctions.GetValidAMD and use DataFunctions.GetValidAMD.ValidAMD().
Check out this.
It's the same problem. You are importing DataFunctions which is a module. I expct there to be a class called DataFunctions in that module which needs to be imported with
from DataFunctions import DataFunctions
...
AMDInstance = DataFunctions.GetValidAMD()
I have a package named 'package'within that i have modules module1.py and module2.py i imported the package as
import package
from package import module1
In module1 i have a function named funcwhenever i import that function as
from module1 import func
and use it, the function as
module1.func(x)
it doesn't work
What is the problem and what should be done??
You can do either:
from module1 import func
func(x)
OR
module1.func(x)
Real world example which should demonstrate how things work:
>>> import os
>>> os.path.abspath("C:/Documents")
'C:\\Documents'
>>>
>>> from os import path
>>> path.abspath("C:/documents")
'C:\\documents'
>>>
>>> from path import abspath
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named path
>>>
>>> from os.path import abspath
>>> abspath("C:/documents")
'C:\\documents'
You can either import as:
from foo import bar
bar(baz)
or:
import foo
foo.bar(baz)
In certain cases, it may also be helpful to:
from foo import bar as qux
qux(baz
There is an extensive tutorial on handling imports available as well.
2 options:
from package.module1 import func
func(x)
2nd option:
from package import module1
module1.func(x)
In Python, once I have imported a module X in an interpreter session using import X, and the module changes on the outside, I can reload the module with reload(X). The changes then become available in my interpreter session.
I am wondering if this also possible when I import a component Y from module X using from X import Y.
The statement reload Y does not work, since Y is not a module itself, but only a component (in this case a class) inside of a module.
Is it possible at all to reload individual components of a module without leaving the interpreter session (or importing the entire module)?
EDIT:
For clarification, the question is about importing a class or function Y from a module X and reloading on a change, not a module Y from a package X.
Answer
From my tests, the marked answer, which suggests a simple reload(X), does not work.
From what I can tell the correct answer is:
from importlib import reload # python 2.7 does not require this
import X
reload( X )
from X import Y
Test
My test was the following (Python 2.6.5 + bpython 0.9.5.2)
X.py:
def Y():
print "Test 1"
bpython:
>>> from X import Y
>>> print Y()
Test 1
>>> # Edit X.py to say "Test 2"
>>> print Y()
Test 1
>>> reload( X ) # doesn't work because X not imported yet
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'X' is not defined
>>> import X
>>> print Y()
Test 1
>>> print X.Y()
Test 1
>>> reload( X ) # No effect on previous "from" statements
>>> print Y()
Test 1
>>> print X.Y() # first one that indicates refresh
Test 2
>>> from X import Y
>>> print Y()
Test 2
>>> # Finally get what we were after
If Y is a module (and X a package) reload(Y) will be fine -- otherwise, you'll see why good Python style guides (such as my employer's) say to never import anything except a module (this is one out of many great reasons -- yet people still keep importing functions and classes directly, no matter how much I explain that it's not a good idea;-).
from modulename import func
import importlib, sys
importlib.reload(sys.modules['modulename'])
from modulename import func
First off, you shouldn't be using reload at all, if you can avoid it. But let's assume you have your reasons (i.e. debugging inside IDLE).
Reloading the library won't get the names back into the module's namespace. To do this, just reassign the variables:
f = open('zoo.py', 'w')
f.write("snakes = ['viper','anaconda']\n")
f.close()
from zoo import snakes
print snakes
f = open('zoo.py', 'w')
f.write("snakes = ['black-adder','boa constrictor']\n")
f.close()
import zoo
reload(zoo)
snakes = zoo.snakes # the variable 'snakes' is now reloaded
print snakes
You could do this a few other ways. You could automate the process by searching through the local namespace, and reassigning anything that was from the module in question, but I think we are being evil enough.
If you want to do this:
from mymodule import myobject
Do this instead:
import mymodule
myobject=mymodule.myobject
You can now use myobject in the same way as you were planning (without the tiresome unreadable mymodule references everywhere).
If you're working interactively and want to reload myobject from mymodule you now can using:
reload(mymodule)
myobject=mymodule.myobject
If you're working in a jupyter environment, and you already have from module import function can use the magic function, autoreload by
%load_ext autoreload
%autoreload
from module import function
The introduction of the autoreload in IPython is given here.
assuming you used from X import Y, you have two options:
reload(sys.modules['X'])
reload(sys.modules[__name__]) # or explicitly name your module
or
Y=reload(sys.modules['X']).Y
few considerations:
A. if the import scope is not module-wide (e,g: import in a function) - you must use the second version.
B. if Y is imported into X from another module (Z) - you must reload Z, than reload X and than reload your module, even reloading all your modules (e,g: using [ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ]) might reload X before reloading Z - and than not refresh the value of Y.
reload() module X,
reload() module importing Y from X.
Note that reloading won't change already created objects bound in other namespaces (even if you follow style guide from Alex).
Just to follow up on AlexMartelli's and Catskul's answers, there are some really simple but nasty cases that appear to confound reload, at least in Python 2.
Suppose I have the following source tree:
- foo
- __init__.py
- bar.py
with the following content:
init.py:
from bar import Bar, Quux
bar.py:
print "Loading bar"
class Bar(object):
#property
def x(self):
return 42
class Quux(Bar):
object_count = 0
def __init__(self):
self.count = self.object_count
self.__class__.object_count += 1
#property
def x(self):
return super(Quux,self).x + 1
def __repr__(self):
return 'Quux[%d, x=%d]' % (self.count, self.x)
This works just fine without using reload:
>>> from foo import Quux
Loading bar
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> Quux()
Quux[2, x=43]
But try to reload and it either has no effect or corrupts things:
>>> import foo
Loading bar
>>> from foo import Quux
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> reload(foo)
<module 'foo' from 'foo\__init__.pyc'>
>>> Quux()
Quux[2, x=43]
>>> from foo import Quux
>>> Quux()
Quux[3, x=43]
>>> reload(foo.bar)
Loading bar
<module 'foo.bar' from 'foo\bar.pyc'>
>>> Quux()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "foo\bar.py", line 17, in __repr__
return 'Quux[%d, x=%d]' % (self.count, self.x)
File "foo\bar.py", line 15, in x
return super(Quux,self).x + 1
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> Quux().count
5
>>> Quux().count
6
>>> Quux = foo.bar.Quux
>>> Quux()
Quux[0, x=43]
>>> foo.Quux()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "foo\bar.py", line 17, in __repr__
return 'Quux[%d, x=%d]' % (self.count, self.x)
File "foo\bar.py", line 15, in x
return super(Quux,self).x + 1
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> foo.Quux().count
8
The only way I could ensure the bar submodule was reloaded was to reload(foo.bar); the only way I access the reloaded Quux class is to reach in and grab it from the reloaded sub module; but the foo module itself kept holding onto the original Quux class object, presumably because it uses from bar import Bar, Quux (rather than import bar followed by Quux = bar.Quux); furthermore the Quux class got out of sync with itself, which is just bizarre.