Python's From and import execution process analysis

Source: Internet
Author: User

Original link: http://blog.csdn.net/lis_12/article/details/52883729

Question 1

In the same directory, there are two Python files, a.py,b.py

#a.py fromBImportDclassC (object):Pass#b.py fromAImportCclassD (object):Pass" "execution a.py results: Traceback (most recent call last): File "a.py", line 4, in <module> from B import D File "b.py", L Ine 4, in <module> from A import C File "a.py", line 4, in <module> from B import dimporterror:cannot Import name D" "

Why?

Execution mechanism for from B import D

You can use Sys.modules to see if a B module is included, such as viewing the OS module, entering

>>> sys.modules[' OS '].

    1. Existence of Module B

      If Sys.modules has a key of B, it gets the corresponding value, that is, the Modules object, and then finds and obtains an object with the name D from the __dict__ list in module B, and throws an exception if it does not exist.

      The __dict__ list of Module B can be viewed using Dir (b).

    2. No module B exists

      If the key does not exist, then a module object is created for B, at which point the __dict__ list of the module object is empty, and then the search path is found and executed b.py to populate the __dict__ list of the module B object, and then find the object named D from the __dict__ list. Throws an exception if it is not found.

      Note: module, meaning of modules

Review Sys.modules changes according to the code above

#a.py#!/usr/bin/python#-*-coding:utf-8-*-ImportSYSTry:    Print 'module B:%s'%sys.modules['B']exceptexception,e:PrintU'No module B%s'%eTry:    Print 'module A:%s'%sys.modules['A']exceptexception,e:PrintU'No module A%s'%e fromBImportDclassC (object):Pass#b.py fromAImportCclassD (object):Pass" "execution a.py Result: no module B ' B ' does not have module a ' a ' module B: <module ' B ' from ' B.pyc ' >module A: <module ' a ' from ' a.py ' &G T Traceback (most recent): File "a.py", line 4, in <module> from B import D File "b.py", line 4, in < ;module> from A import C File "a.py", line 4, in <module> from B import dimporterror:cannot import name D 
Question 1 Answer
    1. Run a.py, when executed to the from B import D statement, because the b.py has not been run, so there is no B in Sys.modules. A key B is created and assigned to the module B object, except that the module B object is empty and there is nothing in it;
    2. Then, pausing to execute the other statements of a.py, Python finds b.py under the search path, finds b.py in the same directory, and runs, in order to populate the __dict__ list in the module B object. When executing to from A import C, The sys.modules is also checked for a module that is known as a, but because a.py has not yet been read, the corresponding information is not cached in Sys.modules. Similarly, Python creates a key A and assigns an empty module a object. Pause the execution of the b.py and look for, Executes the a.py from the beginning.
    3. At this point, it will be executed again to the from B import D statement, because in the first step when the key B's Module B object has been created, it is directly obtained, but at this time the __dict__ list in the module B object is empty, there is nothing in it, so I can't find an object named D. sys.modules , throws an exception.

Compared with the running results, is not very consistent--!

(limited presentation capacity, see the Code Bar--)

Question 2 Replace the from import with the import
#a1.py#!/usr/bin/python#-*-coding:utf-8-*-ImportSYSTry:    Print 'module B1:%s'%sys.modules['B1']exceptexception,e:PrintU'No module B1%s'%eTry:    Print 'module A1:%s'%sys.modules['A1']exceptexception,e:PrintU'No module A1%s'%eImportB1classC (object):PassTry: b1.d ()exceptexception,e:PrintU'no attribute d in B', E#b1.pyImportA1classD (object):Pass" "execution a.py results: No module B1 ' B1 ' without module A1 ' A1 ' module B1: <module ' B1 ' from ' B1.pyc ' >module A1: <module ' A1 ' from ' a1.py ' >b has no attribute D ' module ' object has no attribute ' d '" "

By the results of the program, we will from...import ... After changing to import, the program will not go wrong, but why does it throw an exception when calling B1.D ()?

Question 2 Answer
    1. Run a1.py, when executing to the import B1 statement, because the b1.py has not been run, so there is no B1 this key in Sys.modules. Creates a key B1 and assigns a module B1 object, except at this point the module object is empty, there is nothing in it;

    2. Then, pausing execution of A1.py's other statements, Python finds b1.py under the search path, finds b1.py in the same directory, and runs, in order to populate the __dict__ list in the module B1 object. When executing to import A1, The sys.modules is also checked for A1 modules, but because a1.py has not been read, the corresponding information is not cached in the sys.modules. Then, again, the Python A module A1 object that creates a key A1 and assigns an empty value. Pauses execution b1.py and looks for, executes a1.py from the beginning.

    3. At this point, the import B1 statement is executed again, because the module B1 object has been created in Sys.modules at the first step, the module B1 object already exists and does not need to execute b1.py, so the other content in a1.py continues.

      Note: At this point the module B1 is still empty and there is nothing in it.

    4. When executing to B1.D (), an exception is thrown because an object named D is not found in the __dict__ list of the module B1 object.

Issue 3 Modify the program in question 1 to make it work correctly
# a2.py  from Import D class C (object):     Pass # b2.py class D (object):     Pass  from Import C

Brief description:

a2.py->b2.py->a2.py, the D attribute is already in the B2 __dict__ list, so there is no error ... Although this writing will not be an error, but strongly do not recommend this write ....

Summarize

When the Python program to import other modules, to avoid the loop import, or will always out of the intention of the problem ....

Note: Circular import, that is, a file import the B,b file and import a.

Re-importing Modules
If you update a module that has already been imported with an import statement, the built-in function reload () can re-import and run the updated module code. It requires a module object as a parameter. For example:
Import Foo
... some code ...
Reload (foo) # re-import foo

The new import code is used for the module after reload () is run, but reload () does not update objects created with the old module, so there is a possibility that the old and new versions of the object will coexist. * Note * Modules compiled with C or C + + cannot be re-imported through the reload () function. Remember a principle, except in the debugging and development process, do not use the reload () function

Python's From and import execution process analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.