오류코드

#ExceptionExample2.py

import MyError
def say_nick(nick):
    if nick == '바보':
        raise MyError()
    print(nick, "from Example2")
    
try:
    # say_nick('천사')
    say_nick('바보')
except MyError:
    print("허용되지 않는 별명입니다.")
# MyError.py

class MyError(Exception):
    pass

 

오류내용

모듈 객체는 호출이 불가능하다. 

Traceback (most recent call last):
  File "C:\Users\iksflow\PycharmProjects\python-study\ch05\ExceptionExample2.py", line 9, in <module>
    say_nick('바보')
  File "C:\Users\iksflow\PycharmProjects\python-study\ch05\ExceptionExample2.py", line 4, in say_nick
    raise MyError()
TypeError: 'module' object is not callable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\iksflow\PycharmProjects\python-study\ch05\ExceptionExample2.py", line 10, in <module>
    except MyError:
TypeError: catching classes that do not inherit from BaseException is not allowed

 

원인

파이썬의 모듈을 함수처럼 ()를 사용해 호출하려 했기 때문에 발생한 문제이다.
위 코드를 모듈명과 클래스 명을 동일하게 생성해서 MyError클래스의 인스턴스를 생성하는 코드로 착각한것이 원인이었다.

오류를 발생시키게 된 원인은 자바에 너무 익숙한 탓이었다. 
자바에서는 java파일을 생성하면 반드시 파일명과 동일한 class를 생성해야 한다는 규칙이 있다.
그래서 import문을 작성할 때 내가 불러오는게 파일인지 클래스인지 신경 쓸 필요가 없었고, module = class라는 생각으로 코딩했던것이다.
하지만 파이썬에서는 자바와는 다르게 파일명과 클래스명을 일치시켜야한다는 제약이 없다.
따라서 파일명으로 클래스를 유추할 수 없기 때문에 모듈(파일), 클래스로 명확히 구분해야한다.

 

해결방법

# 방법1. from 모듈 import 객체 의 형식으로 작성하기
from MyError import MyError

# 방법2. import 모듈의 형식으로 모듈을 import하고
# MyError.MyError 처럼 명시적으로 모듈명과 객체명을 작성해서 사용하기

import MyError
def say_nick(nick):
    if nick == '바보':
        raise MyError.MyError()
    print(nick)
    
try:
    # say_nick('천사')
    say_nick('바보')
except MyError.MyError:
    print("허용되지 않는 별명입니다.")


모듈객체를 호출하려 했던것이 오류 원인이므로 원래 의도에 맞게끔  MyError클래스 생성자를 호출하도록 수정해야한다.

파이썬에서 import를 통해 다른 모듈, 클래스하는 방법은 아래의 2가지가 있다.

1. import 모듈1, 모듈2, 모듈3...
2. from 모듈 import 객체(변수, 함수, 클래스)

따라서 해결 방법도 2가지가 존재한다.

첫번째 방법 : import 모듈 형식 사용하기

이 경우 모듈.객체의 형식으로 호출해야한다. 
객체를 호출하기위해 명시적으로 모듈명을 작성해야 하는 이유는 아마도 모듈을 여러개 import하는 경우 객체이름만으로는 어떤모듈의 객체인지 찾을 수 없기 때문일 것이다.

두번째 방법 : from 모듈 import 객체 형식 사용하기

from을 사용하면 모듈을 한개만 import 할 수 있기 때문에 객체명을 바로 사용해도 호출에 문제가 생기지않는다.

 

리뷰

이번 경험을 계기로 import문을 사용하는 방법을 확실히 알게되었다.
아직 파이썬에 익숙하지 않은 탓인지 모르겠으나 모듈명과 클래스명을 동일시 하면 혼동하는 경우가 종종 생길것 같다.
파이썬의 코딩컨벤션을 확인해서 모듈과 클래스명의 명명규칙을 더 알아봐야겠다.