Python2012.09.03 16:42

python 은 정말 강력한 언어이지만, import 방식은 C와 비슷하게 매우 구식이다.

그래서 체계적으로 소스를 구성하지 않고 import를 남발하다보면, circular import 문제에 부딪히게 된다. 즉 순환하여 import 하는 경우 "cannot import name bar"와 같이 특정 모듈을 import 할 수 없어서 소스 실행이 되지 않는다.


우선 간략히 해결방법을 적으면,

1. 모듈을 구조적으로 설계하여, 상호 import하지 않도록 한다.

라이브러리성 모듈로 잘 분할해서 저장하고, 이 라이브러리성 모듈을 조합해서 실행하는 모듈은 소수만 유지하는 것이다.


2. from package import module 대신 import package.module을 사용한다.

from package import module 구문(statement)은 package가 생성(__init__.py호출)된 후에 사용할 수 있지만,  import package.module 구문은 바로 사용할 수 있기 때문이다. (아래 실행 결과 참조)


3. 도저히 해결할 수 없을만큼 import가 꼬인 경우, importlib.import_module('module', 'package') 를 사용한다.

import package.module 형태로도 이 에러가 해결되지 않는 경우가 있었는데, 꼬인 모듈들의 import문을 모두 importlib.import_module('module','package')로 치환해서 해결했다.



* from package import module의 실행 순서

# bage/test/__init__.py

print 'bage.test.__init__.py'


# bage/test/a.py

print 'a.py before "from bage.test import b"'

from bage.test import b

print 'a.py after "from bage.test import b"'

if __name__ == '__main__':

    pass


# bage/test/b.py

print 'b.py before "from bage.test import a"'

from bage.test import a

print 'b.py after "from bage.test import a"'


# 실행 결과 (raised circular import error)

# python a.py

a.py before "from bage.test import b"

bage.test.__init__.py

b.py before "from bage.test import a"

a.py before "from bage.test import b"

Traceback (most recent call last):

  File "C:\Users\bage\git\BageUtil2012.git\BageUtil2012\bage\test\a.py", line 8, in <module>

    from bage.test import b

  File "C:\Users\bage\git\BageUtil2012.git\BageUtil2012\bage\test\b.py", line 7, in <module>

    from bage.test import a

  File "C:\Users\bage\git\BageUtil2012.git\BageUtil2012\bage\test\a.py", line 8, in <module>

    from bage.test import b

ImportError: cannot import name b


* import package.module의 실행 순서

# bage/test/__init__.py

print 'bage.test.__init__.py'


# bage/test/a.py

print 'a.py before "import b"'

import b

print 'a.py after "import b"'

if __name__ == '__main__':

    pass


# bage/test/b.py

print 'b.py before "import b"'

import a

print 'b.py after "import b"'


# 실행 결과 (not raised circular import error)

# python a.py

a.py before "import b"

b.py before "import b"

a.py before "import b"

a.py after "import b"

b.py after "import b"

a.py after "import b"












신고
Posted by 바게 BAGE