{"id":606,"date":"2018-07-11T11:50:59","date_gmt":"2018-07-11T11:50:59","guid":{"rendered":"http:\/\/ijbd.eu\/?p=606"},"modified":"2018-07-11T11:50:59","modified_gmt":"2018-07-11T11:50:59","slug":"are-circular-imports-in-python-evil","status":"publish","type":"post","link":"https:\/\/ijbd.eu\/?p=606","title":{"rendered":"Are circular imports in python evil?"},"content":{"rendered":"<p>Circular imports can be confusing because import does two things:<br \/>\n1. executes imported module code<br \/>\n2. adds imported module to global symbol table of importing module<br \/>\nThe former is done only once, while the latter at each import statement. Circular import creates situation when importing module uses imported one with partially executed code. In consequence it will not see objects created after import statement, below code sample demonstrates it.<\/p>\n<p>main.py<\/p>\n<pre>print 'import b'\r\nimport b\r\nprint 'a in globals() {}'.format('a' in globals())\r\nprint 'import a'\r\nimport a\r\nprint 'a in globals() {}'.format('a' in globals())\r\nif __name__ == '__main__':\r\nprint 'imports done'\r\nprint 'b has y {}, a is b.a {}'.format(hasattr(b, 'y'), a is b.a)<\/pre>\n<p>b.by<\/p>\n<pre>print \"b in, __name__ = {}\".format(__name__)\r\nx = 3\r\nprint 'b imports a'\r\nimport a\r\ny = 5\r\nprint \"b out\"<\/pre>\n<p>a.py<\/p>\n<pre>print 'a in, __name__ = {}'.format(__name__)\r\nprint 'a imports b'\r\nimport b\r\nprint 'b has x {}'.format(hasattr(b, 'x'))\r\nprint 'b has y {}'.format(hasattr(b, 'y'))\r\nprint \"a out\"<\/pre>\n<p>python main.py output with comments<\/p>\n<pre>import b\r\nb in, __name__ = b # b code execution started\r\nb imports a\r\na in, __name__ = a # a code execution started\r\na imports b # b code execution is already in progress\r\nb has x True\r\nb has y False # b defines y after a import,\r\na out # module a code executed\r\nb out\r\na in globals() False # import only adds a to main global symbol table\r\nimport a\r\na in globals() True\r\nimports done\r\nb has y True, a is b.a True # all b objects are available<\/pre>\n<p>Circular imports are not the ultimate evil to be avoided at all cost. In some frameworks like Flask they are quite natural and tweaking your code to eliminate them does not make the code better.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Circular imports can be confusing because import does two things: 1. executes imported module code 2. adds imported module to global symbol table of importing module The former is done only once, while the latter at each import statement. Circular import creates situation when importing module uses imported one with partially executed code. In consequence [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-606","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p4qwq1-9M","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ijbd.eu\/index.php?rest_route=\/wp\/v2\/posts\/606","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ijbd.eu\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ijbd.eu\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ijbd.eu\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/ijbd.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=606"}],"version-history":[{"count":2,"href":"https:\/\/ijbd.eu\/index.php?rest_route=\/wp\/v2\/posts\/606\/revisions"}],"predecessor-version":[{"id":608,"href":"https:\/\/ijbd.eu\/index.php?rest_route=\/wp\/v2\/posts\/606\/revisions\/608"}],"wp:attachment":[{"href":"https:\/\/ijbd.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=606"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ijbd.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=606"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ijbd.eu\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=606"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}