When is import required?

mod1.py

import mod2 class Universe: def __init__(self): pass def answer(self): return 42 u = Universe() mod2.show_answer(u) 

mod2.py

 #import mod1 -- not necessary def show_answer(thing): print thing.answer() 

Based on the background of C ++, I got the feeling that you need to import a module containing the definition of the Universe class before the show_answer function works. That is, everything had to be announced before it could be used.

Am I right in thinking that this is not necessary? This is a duck, right? So if import is not required to view class methods, would I at least need it to define the class and top-level functions of the module itself?

In one script that I wrote, I even went as far as writing the base class to declare an interface with a set of methods, and then output specific classes to inherit from that interface, but I think I'm getting it now - which is wrong in Python, and is the object checked by a certain method at runtime at the point where the call is made?

I understand that Python is much more dynamic than C ++, it took me a while to see how little code you really need to write!

I think I know the answer to this question, but I just wanted to get clarification and make sure I'm on the right track.

UPDATE: Thanks for all the answers, I think I should clarify my question now:

Does mod2.show_answer () need to import (of any description) to know that this thing has a method called answer (), or is it determined dynamically at runtime?

+4
source share
7 answers

import - all about names - basically “bare names” that are connected at the top level (global AKA level, AKA module level names) in a specific module, say mod2 . When you execute import mod2 , you will get the mod2 namespace as an available name (the top level in your own module, if you do import as the top level, as it is most common, but local import inside the function will make mod2 local variable for this function, etc. d.); and therefore, you can use mod2.foobar to access the foobar name, which is linked at the top level in mod2 . If you do not need to refer to such names, you do not need import mod2 in your own module.

+4
source

In this case, you are right: show_answer () gets the object from which it calls the answer method. As long as the object specified by show_answer () has such a method, it doesn't matter where the object comes from.

If, however, you wanted to create an instance of Universe inside mod2, you will have to import mod1 because Universe is not in the namespace of mod2, even after mod2 has been imported mod1.

+6
source

Think that import is more like a linker.
With "import mod2" you just tell python that it can find the function in the mod2.py file

+1
source

import in Python loads the module into the given namespace. Thus, as if def show_answer really existed in mod1.py module. Because of this, mod2.py does not need to know about the Universe class and therefore you do not need to import mod1 from mod2.py.

+1
source

Actually, in this case, importing mod1 into mod2.py should not work.
Wouldn't that create a round link?

+1
source

In fact, according to this explanation , circular import will not work the way you want it to work: if you uncomment import mod1 , the second module still does not know about Universe .

I think that is quite reasonable. If both of your files require access to the type of a specific object, for example Universe , you have several options:

  • If your program is small, just use one file
  • If this is important, you need to decide if your files should know how Universe implemented, perhaps passing an object of an unknown type to show_answer fine.
  • If this does not work for you, be sure to put Universe in a separate module and download it first.
+1
source

I know little about C ++, so I can not directly compare it, but ..

import basically loads another Python script ( mod2.py ) into the current script (top level mod1.py ). This is not so much a link, it is closer to eval

For example, in Python'ish psuedo-code:

 eval("mod2.py") 

matches ..

 from mod2 import * 

.. it executes mod2.py and makes available functions / classes available in the current script.

Both of the above snippets will allow you to call show_answer() (well, eval doesn't work that way, so I called it pseudo-code!)

 import mod2 

.. basically the same thing, but instead of putting all the functions in the “upper level”, it injects them into the mod2 module, so you call show_answer by doing.

 mod2.show_answer 

I correctly understood [import into mod2.py] is not needed?

That's right. Actually, if you try to import mod1 from mod2 , you will get a circular dependency error (since mod2 then tries to import mod1 , etc.)

+1
source

Source: https://habr.com/ru/post/1286574/


All Articles