본문 바로가기
프로그래밍/데이터분석

Jupyter Notebook, No Attribute 에러 해결을 위한 모듈 리로드(reload) 방법

by K-인사이터 2024. 4. 1.
반응형

안녕하세요
K-인사이트입니다. 
 

 
Jupyter Notebook과 같은 대화형 개발 도구를 이용해 데이터를 분석하다보면 반복해서 사용하는 함수 등을 별도의 python 소스코드로 저장해서 개발하는 경우가 있습니다. 예를 들어, 그래프를 그리거나 텍스트 날짜 정보를 변환하거나 등이 있습니다. 그런데, import 구문들이 위치하는 셀(Cell)을 재실행해도 새롭게 추가한 함수를 찾을 수 없다는 AttributeError: module ‘xxx’ has no attribute ‘yy’ 에러를 만나는 경우가 있습니다.
 

No Attribute 에러

IPython, Jupyter Notebook 과 같은 대화형 개발 도구는 임포트한 모듈에 함수를 추가할 경우 아래와 같은 에러가 발생합니다. 즉, 변경된 소스코드의 내용이 인터프리터 상에 반영되지 않음을 의미합니다. 이러한 대화형 개발 도구의 특징은 중복된 코드를 싫어하는 분석가들에게 짜증을 안겨주기도 합니다.

>> import util
# util.py 파일 내에 mod 함수를 추가
>> util.mod(1, 2)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[10], line 1
----> 1 util.mod(1, 2)

AttributeError: module 'util' has no attribute 'mod'

 
위 사례는 분석가가 자주 사용되는 함수들을 util.py 파일을 통해 관리할 때 발생합니다. Jupyter Notebook 에서 데이터 분석을 하는 도중에 util.py 파일에 mod 함수가 필요하다는 사실을 깨달은 개발자는 대화형 개발 도구를 실행한 상태에서 util.py 파일에 mod 함수를 추가하고 셀(Cell)을 재실행합니다. 하지만 아무리 재실행해도 추가된 mod 함수는 반영되지 않고 AttributeError: module 'util' has no attribute 'mod' 라는 에러만 토해냅니다.

 

No Attribute 에러 해결 방법

이 에러를 해결하는 방법은 총 세가지입니다. 첫번째는 커널(Kernel)자체를 다시시작하는 방법입니다. 만약, 여러분이 작업 중인 내용이 있다면 모든 내용은 초기화됩니다. 두번째는 importlib의 reload 를 이용하는 방법입니다. 이 방법은 매번 소스코드가 변경될 때 마다 선언한 셀을 반복해서 재실행해야합니다. 이것도 현명한 방법은 아닙니다. 마지막 세번째 방법으로 autoreload 를 사용하는 방법입니다.

커널 재시작 방법

Jupyter Notebook, JupyterLab과 같은 대화형 도구들은 실행 중인 커널(kernel)을 관리하는 기능을 가지고 있습니다. 메뉴에서 Kernel > Restart Kernel 을 클릭하면 문제가 해결됩니다.

 

importlib 활용 방법

importlib는 사용자가 파이썬의 import 시스템과 상호작용하기 위한 API를 제공하는 빌트인(built-in, 내장) 라이브러리입니다. 이 라이브러리는 reload 함수를 제공하며 이 함수를 실행하면 모듈 코드가 재컴파일되면서 모듈 레벨의 코드 또한 재실행됩니다. 따라서, 파이썬 인터프리터, IPython 커널, Jupyter Notebook, Jupyter Lab 등을 종료하지 않고도 모듈의 수정사항을 반영할 수 있습니다.

 
앞서 예시로 돌아가 여러분의 util.py 파일 내에 mod 함수를 추가하였다면 아래와 같이 reload를 통해서 추가된 함수를 불러 올 수 있습니다.

import util
import importlib
importlib.reload(util)
util.mod(1, 2)

 

autoreload 활용 방법

마지막 방법은 IPython Extension을 이용하는 방법입니다. autoreload는 IPython 공식문서를 통해서 그 정의를 확인할 수 있습니다. 사용자 코드를 실행하기 전에 모듈들을 다시 로드하는 IPython 확장입니다. 아래의 코드 예시처럼 작성해주면 No Attribute 에러가 발생하지 않음을 확인할 수 있습니다.

%load_ext autoreload
%autoreload 2

import util
util.mod(1, 2)

 
만약 util.py 와 같은 소스코드를 관리한다면 아래 예시처럼 맨 상단에 autoreload 구문을 선언해두고 작업하면 실행할 때 마다 최신의 코드가 반영되어 작업을 편리하게 할 수 있습니다.

 

 
%autoreload 2 구문에서 뒤에 오는 숫자의 기능은 아래와 같습니다. 즉, 모든 모듈을 다시 로드하는 설정을 적용한 것입니다. 이 외에도 다양한 옵션이 제공되므로 참고하여 자신의 상황에 맞는 설정을 적용하도록 제어할 수 있습니다.

  • %autoreload, %autoreload now: 모든 모듈을 자동으로 다시로드합니다.
  • %autoreload 0, %autoreload off: 자동으로 다시로드를 비활성화합니다.
  • %autoreload 1, %autoreload explicit: Python 코드를 실행하기 전에 %aimport로 가져온 모든 모듈을 다시로드합니다.
  • %autoreload 2, %autoreload all: 모든 모듈을 다시로드합니다.
  • %autoreload 3, %autoreload complete: 모든 모듈을 다시로드하고, 모듈에 새로운 객체가 추가되면 해당 객체도 다시로드합니다.
  • %autoreload 뒤에 -print 또는 **p**를 추가하면 자동로드 활동을 표준 출력으로 출력합니다. -log 또는 **l**을 추가하면 로그에 출력합니다. 두 옵션을 동시에 사용할 수 있습니다.

맺음말

autoreload는 변경사항이 있을때 즉각 이를 반영해주어서 매우 편리합니다. 만약 autoreload를 모르고 importlib.reload를 통해서 다시 import 하는 과정을 반복하고 있다면 이글이 여러분에게 도움을 줄 것이라고 기대하고 있습니다. 이 외에도 다른 방법을 알고 있다면 댓글을 통해서 소통해주시면 감사하겠습니다.
 
이상입니다.
K-인사이트올림.
 

 

참고

반응형