사냥꾼의 IT 노트

Python 병렬 라이브러리 개발 프로젝트 - 순환 참조 오류 본문

python

Python 병렬 라이브러리 개발 프로젝트 - 순환 참조 오류

가면 쓴 사냥꾼 2023. 1. 12. 21:27

※본 포스팅은 22년 9월~22년 11에 진행된 프로젝트의 연구노트입니다.

 

demo.py를 다음과 같이 분할 후 실행 하면, 순환 참조 오류가 발생한다.

# Set C function : init_model = load model and run model
import ctypes
from ctypes.wintypes import POINT
import sys
from enum import Enum
 
# Set path And Load Library
path =f'./libconnx.so'
connx = ctypes.cdll.LoadLibrary(path)
args = sys.argv
 
# Set C Stucture by python ctypes
class connx_Graph(ctypes.Structure):
    pass
 
class connx_Model(ctypes.Structure):
    _fields_ = [
        ('version', ctypes.c_int32),
 
        ('opset_count', ctypes.c_uint32),
        ('opset_names', ctypes.POINTER(ctypes.POINTER(ctypes.c_char))),
        ('opset_versions', ctypes.POINTER(ctypes.c_uint32)),
 
        ('graph_count', ctypes.c_uint32),
        ('graphs', ctypes.POINTER(ctypes.POINTER(connx_Graph))),
    ]
 
connx_init = connx.connx_init
connx_init.argtypes = None
connx_init.restype = None
 
connx_init_model_name = connx.connx_init_model_name
connx_init_model_name.argtypes = [ctypes.POINTER(ctypes.c_char)]
connx_init_model_name.restype = ctypes.c_int32
 
connx_load_Model = connx.connx_load_Model
connx_load_Model.argtypes = [ctypes.POINTER(connx_Model), ctypes.c_uint32]
connx_load_Model.restype = ctypes.c_int32
 
ret = ctypes.c_int32()
 
connx_init()
model = connx_Model()
print(model)
ret = connx_init_model_name(b'./mnist')
if ret != 0:
    print('connx_init_model_name failed')
exit(1)

순환 참조 오류

ImportError: cannot import name 'connx_init' from partially initialized module 'init_model' (most likely due to a circular import)

순환 참조 오류의 원인은 모듈을 import할 시 작업 폴더 내 동일한 파일명이 존재한다는 것. 한마디로 파일명과 함수명이 같으면 발생하는 오류인 것이다.

그러나 필자의 경우 이는 해당하지 않는다. output_model.py, init_model로 서로 다른 이름을 사용하기 때문이다.

이를 해결하기 위해서는 함수 자체를 정의하지 않는 것이다. 정말 간단한 원리로, ctypes로 받아오는 함수와 파이썬에서 정의해준 함수가 동시에 존재해서 발생했던 것으로 보인다. 이를 해결해 작성한 코드는 다음 포스팅에서 설명한다.