내부에서 예외를 발생시키는 것이 나쁜 형태로 간주 __init__
됩니까? 그렇다면 특정 클래스 변수가 None
잘못된 유형 으로 초기화 될 때 허용되는 오류를 던지는 방법은 무엇입니까?
답변
예외를 발생시키는 __init__()
것은 절대적으로 좋습니다. 생성자 내에서 오류 조건을 나타내는 다른 좋은 방법은 없으며 표준 라이브러리에는 개체를 빌드 할 때 예외가 발생할 수있는 수백 가지의 예제가 있습니다.
물론 발생하는 오류 클래스는 사용자에게 달려 있습니다. ValueError
생성자에 잘못된 매개 변수가 전달 된 경우 가장 좋습니다.
답변
생성자에서 오류를 표시하는 유일한 올바른 방법은 예외를 발생시키는 것입니다. 그렇기 때문에 C ++ 및 예외 안전을 염두에두고 설계된 다른 객체 지향 언어에서 객체의 생성자에 예외가 발생하면 소멸자가 호출되지 않습니다 (객체 초기화가 불완전 함을 의미 함). 파이썬과 같은 스크립팅 언어에서는 그렇지 않습니다. 예를 들어, 다음 코드는 socket.connect ()가 실패하면 AttributeError를 발생시킵니다.
class NetworkInterface:
def __init__(self, address)
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect(address)
self.stream = self.socket.makefile()
def __del__(self)
self.stream.close()
self.socket.close()
그 이유는 연결 시도가 실패한 후 스트림 속성이 초기화되기 전에 불완전한 객체의 소멸자가 호출되기 때문입니다. 생성자로부터 예외를 던지는 것을 피해서는 안됩니다. 파이썬에서 완전히 예외 안전 코드를 작성하는 것이 어렵다고 말하고 있습니다. 일부 파이썬 개발자는 소멸자를 사용하지 않는 것이 좋지만 또 다른 논쟁의 문제입니다.
답변
나는 그것이 나쁜 형식이어야한다는 이유를 보지 못했습니다.
반대로, 오류 코드를 반환하는 대신 예외가 잘 수행되는 것으로 알려진 것 중 하나는 일반적 으로 생성자 가 오류 코드를 반환 할 수 없다는 것입니다. 따라서 적어도 C ++과 같은 언어에서는 예외를 발생시키는 것이 오류를 알리는 유일한 방법입니다.
답변
표준 라이브러리는 다음과 같이 말합니다.
>>> f = file("notexisting.txt")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'notexisting.txt'
또한 나는 그것이 나쁜 형태로 간주되어야하는 이유를 실제로 보지 못합니다.
답변
내장 ValueError
예외에 대한 완벽한 사례라고 생각해야합니다 .
답변
위의 모든 내용에 동의합니다.
예외를 발생시키는 것 외에 객체를 초기화 할 때 무언가 잘못되었다는 신호를 보내는 다른 방법은 없습니다.
클래스의 상태가 그 클래스의 입력에 전적으로 의존하는 대부분의 프로그램 클래스에서 우리는 어떤 종류의 ValueError 또는 TypeError가 발생할 것으로 기대할 수 있습니다.
네트워크 장치를 사용할 수 없거나 캔버스 개체를 쓸 수없는 경우 부작용이있는 클래스 (예 : 네트워킹 또는 그래픽을 수행하는 클래스)에서 초기화 오류가 발생할 수 있습니다. 실패 조건에 대해 가능한 한 빨리 알고 싶어하기 때문에 이것은 나에게 합리적입니다.
답변
init에서 오류를 발생시키는 것은 피할 수 없지만 init에서 너무 많은 작업을 수행하는 것은 나쁜 스타일입니다. 팩토리 또는 의사 팩토리 (설정된 오브젝트를 리턴하는 간단한 클래스 메소드)를 고려해야합니다.
