Python Import at function level VS. Module level

When in doubt, I usually place my import statements at the top of the module. Often this shortens the repetition, which is nice. Is there a performance flaw, however, when only one function (or class) is required?

Does only import when a function is called?

def func(): from task import test 

If so, I suggest that this may be of little efficiency. I also suggest that you could get some added points for faster garbage collection and variable changes, since imported objects would not be added to the global dictionary. As another poster, it's nice to say:

This is mainly due to variable search. To search for a variable in a global area, a dictionary search is required. On the contrary, the compiler sets up static local names and refers to them by index, so dictionary searches are not required.

Are these fair assumptions I'm completely out of base?

thanks

+6
source share
3 answers

Import to a function is imported only when the function starts. Keep in mind that in Python all statements are executed when they occur, and imports are expressions like any other. Top-level imports are imported when a module is imported, as they are top-level instructions in the module.

Your problems with finding names are wrong: the difference is small and should only be taken into account if profiling shows the problem.

I only import modules into the scope for two reasons: 1) to fix problems with cyclic import, which can probably be solved in other ways by refactoring, or 2) if the module is optional and the function is not used by many of my users. In case 2), the module can be completely skipped, and there will be no problems if someone does not call this function.

+4
source

Let's see what the bytecode will look like for the following two functions:

 def func1(): """ test imported each time function is run """ from task import test test() def func2(): """ test was imported at top of module """ test() 

As you can see below, func2() saves a lot of steps using the globally imported test function.

 >>> dis.dis(func1) 3 0 LOAD_CONST 1 (-1) 3 LOAD_CONST 2 (('test',)) 6 IMPORT_NAME 0 (task) 9 IMPORT_FROM 1 (test) 12 STORE_FAST 0 (test) 15 POP_TOP 4 16 LOAD_FAST 0 (test) 19 CALL_FUNCTION 0 22 POP_TOP 23 LOAD_CONST 3 (None) 26 RETURN_VALUE >>> dis.dis(func2) 3 0 LOAD_GLOBAL 0 (test) 3 CALL_FUNCTION 0 6 POP_TOP 7 LOAD_CONST 1 (None) 10 RETURN_VALUE 

Given this in the front, it is probably premature optimization, as pointed out in the delnan comments.

For test located in the global namespace, this is unlikely to cause problems with search performance. The best known way, I think you could see it, if there was a hash clash for test and another name that you use very often, which caused a search for a second name that takes longer. Again, premature optimization to consider this rare case ahead.

+3
source

I think it makes sense to put the import in the definition, if it is not called very often.

0
source

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


All Articles