How does the import keyword work in python?

Let's say I have 3 files:

a.py

from d import d

class a:
    def type(self):
        return "a"
    def test(self):
        try:
            x = b()
        except:
            print "EXCEPT IN A"
            from b import b
            x = b()
        return x.type()

b.py

import sys

class b:
    def __init__(self):
        if "a" not in sys.modules:
            print "Importing a!"
            from a import a
        pass
    def type(self):
        return "b"
    def test(self):
        for modules in sys.modules:
            print modules
        x = a()
        return x.type()

c.py

from b import b
import sys

x = b()
print x.test()

and run python c.py

Python returns with complaints:

NameError: the global name 'a' is not defined

But, IS in sys.modules:

copy_reg
sre_compile
locale
_sre
functools
encodings
site
__builtin__
operator
__main__
types
encodings.encodings
abc
errno
encodings.codecs
sre_constants
re
_abcoll
ntpath
_codecs
nt
_warnings
genericpath
stat
zipimport
encodings.__builtin__
warnings
UserDict
encodings.cp1252
sys
a
codecs
os.path
_functools
_locale
b
d
signal
linecache
encodings.aliases
exceptions
sre_parse
os

And I can change b.py so that:

x = a ()
changes to
x = sys.modules ["a"]. a ()

And python will happily accomplish this.

A couple of questions follow from this:

Why does python say that it does not know what a is when it is in sys.modules?
Does sys.modules use the “correct” way to access class and function definitions?
What is the “right” way to import modules?
those. from import x module
or
import module

+3
4

, , , import.

+3

Python,

: (1) ; (2) ( , ).

, , , a , a b.__init__, b.py. b.test a, NameError.

, Python, import s.

+2

a sys.modules.. sys.modules b. re, .

, . -, a b , ( Fakler Refactoring). , .

b a. , ?

+1

. . , :

if (something)
  from office import desk
else
  from home import desk

... somewhere later in the code...
desk()

(, , ), .

. , .

Regarding whether to use “import foo” from the import string “foo” only, the compromise is more typed (you need to type “foo.bar ()” or just type “bar ()”) the clarity of styles and specificity. If you want your code to be truly readable and unambiguous, just say "import foo" and specify the call everywhere. Remember that it is much harder to read code than to write.

0
source

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


All Articles