I've following use case:
a.py:
import b
import c
c.fun()
b.py:
def fun():
print 'b'
c.py:
def fun():
b.fun()
python a.py doesn't work. It fails with NameError: global name 'b' is not defined.
My understanding of import in python was that a name is added in sys.modules. If that is the case then c.py should also see module b. But apparently that is not the case. So can anyone explain what exactly happens when a module is imported.
Thanks.
The module c.py has to import b in order to get this working...
When importing a module then it is added to the globals-dictionary that is available in the current script's scope only (use "globals()" to print its content)
You have to add all modules which you want to use in that script.
Other way to pass that module in function argument and after that you can call that modules method.
The other way is to add it in _ _ builtins _ _ which is better explain in other post
You have added b and c to the a module, but but not to the c module. When you are inside a module, you can only see what has been added to it. b and c are added to sys.modules, but you haven't imported sys, and you aren't using sys.modules['b'].
Related
I have the following situation:
The first file, named a.py contains:
var = 2
The second file, named b.py contains:
def prnt():
print(var)
The third file, named c.py contains:
from a import *
from b import *
prnt() # NameError: name 'var' is not defined
and raises the given error. I always thought that the import statement basically "copies" code into the calling namespace, so it should be the same as:
var = 2
def prnt():
print(var)
prnt()
but apparently this is not the case. What am I missing?
When you import a module, the code in that module is run by the interpreter (see this for example; add a print statement in there and you'll see it in action). Therefore you can't use variables etc without defining them or importing them.
In b.py do this at the top:
from a import var
Then, unless you need var in c.py, you won't need to import anything from a.py in c.py.
I know this is fake code, but avoid using globals in your functions.
Sometimes, I see examples like this, but I don't understand how do they work. Imported module uses function without any places in which this function is set to use. Please can someone explain me how to use them.
Example:
from some_package import *
def some_func():
# do_something
pass
imported_func()
And then imported_func somehow defines some_func and uses it. How is this implemented?
When I tried to call some_func from module.py I received an error. Again: idea is to use function from imported file which was defined in importing file. I couldn't find answer in google.
I tried:
from f.module import *
obj = cls()
def some_func():
for _ in range(100):
print("smth")
obj.imported_func()
Code in main.py
class cls:
#staticmethod
def imported_func():
some_func()
Code in module.py
I have main.py and folder f in one directory. In folder f I have module.py
The way to do this is at first import __main__ then call __main__.some_func(), but remember, it's not a good practice because at least you are reserving name, what can become common reason for errors.
In a main *.py, the statement
from myModule import a,b,c
imports the module 'myModule', and creates references in the current namespace to the given objects. Or in other words, you can now use a and b and c in your program. But you need to use, for example:
print(myModule.a)
Now, I need to use the statement:
from myModule import *
and I need to access, in my main *.py file, at the values of some variables declared in 'myModule', for example:
print(a)
I tried to use globals() to declare global variables but then they are not imported in the current namespace.
Does anyone know hoe to solve this??
Thanks
Question isn't clear but you can import modules with any moniker you want with:
import thing as t
And to access:
t.thingFunction.(foo)
In module A, I import module B. Then, in module C, I import module A. In module C, will I be able to use the content of module B implicitly via the import of module A, or will I have to explicitly import it into module C?
That should work just fine. However, it would save you some trouble to explicitly import the module as well if only to keep track in your head when looking back at code
If you have any other questions about importing, try taking a gander to this article here
https://docs.python.org/3/reference/import.html
It should help.
Yes, it will work.
I think however you'll have to do:
import moduleB
rather than:
from moduleB import methodX
A simple example down below to give you a start but really you should read the basic tutorial and give it a go first
#A.py
import B
def func_in_a():
B.func_from_b
#C.py
import A
A.func_in_a():
It works fine.
If C imports A (C.py : import A) and A imports B (A.py : import B) and in B you have a function
def funcb():
return `foo`
you can call it from module C :
res = A.B.funcb()
and it will give res = 'foo'
There is a strange behavior of isinstance if used in __main__ space.
Consider the following code
a.py:
class A(object):
pass
if __name__ == "__main__":
from b import B
b = B()
print(isinstance(b, A))
b.py
from a import A
class B(A):
pass
main.py
from a import A
from b import B
b = B()
print(isinstance(b, A))
When I run main.py, I get True, as expected, but when I run a.py, I am getting False. It looks like the name of A is getting the prefix __main__ there.
How can I get a consistent behavior?
I need this trick with import of B in a.py to run doctest on file a.py.
WSo what happens when you run a.py is that Python reads a.py and executes it. While doing so, it imports module b, which imports module a, but it does not reuse the definitions from parsing it earlier. So now you have two copies of the definitions inside a.py, known as modules __main__ and a and thus different __main__.A and a.A.
In general you should avoid importing modules that you are executing as well. Rather you can create a new file for running doctests and use something like
import a
import doctest
doctest.testmod(a)
and remove the __main__ part from module a.
Chain of events:
The a.py script is called.
The class A statement is executed, creating A in the __main__
namespace.
b is imported.
In b.py a is imported.
The class A statement is executed, creating A in the a namespace.
This A in the a namespace has no relation to the A in the
__main__ namespace other than having been generated by the same
code. They are different objects.
I agree with Helmut that it is best to avoid such circular imports. However, if you wish to fix your code with minimal changes, you could do the following:
Let's rename b.py --> bmodule.py so we can distinguish b the module from b the variable (hopefully in your real code these names are already distinct):
class A(object):
pass
if __name__ == "__main__":
import bmodule
b = bmodule.B()
print(isinstance(b, bmodule.A))
prints
True