답변:
이 assert
문장은 거의 모든 프로그래밍 언어로 존재합니다. 나중에 다른 작업의 부작용으로 발생하기보다는 원인이 분명한 프로그램의 문제를 조기에 감지하는 데 도움이됩니다.
당신이 할 때 ...
assert condition
... 프로그램에 해당 조건을 테스트하라고 지시하고 조건이 거짓이면 즉시 오류를 트리거합니다.
파이썬에서는 대략 다음과 같습니다.
if not condition:
raise AssertionError()
파이썬 쉘에서 사용해보십시오 :
>>> assert True # nothing happens
>>> assert False
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
어설 션에는 선택적 메시지가 포함될 수 있으며 인터프리터를 실행할 때 비활성화 할 수 있습니다.
어설 션이 실패한 경우 메시지를 인쇄하려면
assert False, "Oh no! This assertion failed!"
마십시오 하지 전화 괄호를 사용 assert
하는 함수처럼. 성명서입니다. 그렇게 assert(condition, message)
하면 첫 번째 매개 변수로 튜플을 assert
사용하여를 실행합니다 (condition, message)
.
그것들을 비활성화하는 것에 관해서 는 , python
최적화 모드에서 실행될 때 , 어디 에서 assert 문도 무시됩니다. 플래그를 전달하십시오 .__debug__
False
-O
python -O script.py
if not condition: raise AssertError()
왜 assert를 사용해야합니까? 더 짧은 if not condition
진술서 가 아닌 어설 션이 더 좋은 조건이 있습니까?
if
). 더 많은 정보를 원하시면 문서를 읽으십시오 :)
assert
그러나 모든 답변을 읽은 후에는 원하는 것이 없습니다!
괄호를 조심하십시오. 위에서 지적했듯이 파이썬 3에서는 assert
여전히 구문입니다 . 그래서와 print(..)
비슷하게, assert(..)
또는을 외삽 할 수도 raise(..)
있지만 그렇게해서는 안됩니다.
이것은 다음과 같은 이유로 중요합니다.
assert(2 + 2 == 5, "Houston we've got a problem")
달리 작동하지 않습니다
assert 2 + 2 == 5, "Houston we've got a problem"
첫 번째가 작동하지 않는 이유는로 bool( (False, "Houston we've got a problem") )
평가되기 때문 True
입니다.
성명서 assert(False)
에서 False
이것은 그 주위의 중복 괄호 이며 내용으로 평가됩니다. 그러나 assert(False,)
괄호는 이제 튜플이며 비어 있지 않은 튜플 True
은 부울 컨텍스트에서 평가됩니다 .
assert (2 + 2 = 5), "Houston we've got a problem"
괜찮을까요?
assert (2 + 2 = 5), "Houston we've got a problem"
작동하지 않지만 ... assert 문과 관련이 없습니다. 조건이 아니기 때문에 조건이 작동하지 않습니다. 잠깐만 요 =
.
다른 답변에서 언급했듯이 assert
주어진 조건이 true가 아닌 경우 예외를 던지는 것과 유사합니다. 중요한 차이점은 최적화 옵션을 사용하여 코드를 컴파일하면 어설 션 문이 무시된다는 것 -O
입니다. 이 문서 는 assert expression
다음과 동등한 것으로 더 잘 설명 될 수 있다고 말합니다
if __debug__:
if not expression: raise AssertionError
이 방법은 코드를 철저히 테스트 한 다음 어설 션 사례가 실패하지 않는 것이 좋을 때 최적화 된 버전을 릴리스하려는 경우 유용합니다. 최적화가 설정되면 __debug__
변수가 False가되고 조건 평가가 중지됩니다. 이 기능은 또한 당신이 주장에 의존하고 그들이 사라 졌다는 것을 모르는 경우에 당신을 붙잡을 수 있습니다.
if Not Error: raise Exception(“ this is a error”)
? 이렇게하면 사용자가 오류를 실행할 때 프로그램에서 여전히 오류의 원인을 표시합니다.
assert
명령문을 사용해야 합니까? 여기에서는 프로그램이 최종 사용자에게 릴리스 될 때 -O 플래그를 사용하므로 모든 버그가 제거되었다고 가정합니다. 따라서 모든 오류 또는 프로그램 충돌은 계약에 따라 유효하지만 프로그램이 처리 할 수없는 프로그램에 대한 입력으로 인한 것입니다. 따라서 사용자에게 경고해야합니다.
Python에서 주장의 목표는 개발자에게 프로그램에서 복구 할 수없는 오류 를 알리는 것입니다 .
어설 션은 "파일을 찾을 수 없음"과 같이 사용자가 수정 조치를 취할 수있는 (또는 다시 시도 할 수있는) 예상되는 오류 조건을 나타 내기위한 것이 아닙니다.
그것을 보는 또 다른 방법은 어설 션이 코드의 내부 자체 검사 라고 말하는 것입니다 . 코드에서 일부 조건을 불가능하다고 선언하여 작동 합니다. 이러한 조건이 유지되지 않으면 프로그램에 버그가 있음을 의미합니다.
프로그램에 버그가없는 경우 이러한 조건이 발생하지 않습니다. 그러나 그 중 하나 가 발생하면 어떤 "불가능한"조건이 트리거되었는지 정확하게 알려주는 어설 션 오류와 함께 프로그램이 중단됩니다. 이를 통해 프로그램의 버그를 훨씬 쉽게 추적하고 수정할 수 있습니다.
다음은 내가 쓴 Python의 주장에 대한 자습서 의 요약입니다 .
Python의 assert 문은 디버깅 오류이며 런타임 오류 처리 메커니즘이 아닙니다. 어설 션 사용의 목표는 개발자가 버그의 근본 원인을 더 빨리 찾을 수 있도록하는 것입니다. 프로그램에 버그가 없으면 어설 션 오류가 발생하지 않아야합니다.
assert
진술과 사용시기 를 이해하는 데 매우 도움 이됩니다. 기사에서 소개 한 여러 용어를 이해하려고합니다.
assert store.product_exists(product_id), 'Unknown product id'
디버그가 꺼져 user
있으면 admin
제품을 삭제할 수 없으므로 좋은 방법이 아닙니다 . 당신 assert user.is_admin()
은 unrecoverable
오류 로 간주 합니까? 왜 이것이 self-check
아닌가?
assert statement
캔트, price
또한 사용자 입력 간주? assert user.is_admin()
데이터 유효성 검사로 간주 하지만 왜 그렇지 assert price
않습니까?
다른 사람들은 이미 문서에 대한 링크를 제공했습니다.
대화식 쉘에서 다음을 시도 할 수 있습니다.
>>> assert 5 > 2
>>> assert 2 > 5
Traceback (most recent call last):
File "<string>", line 1, in <fragment>
builtins.AssertionError:
첫 번째 문장은 아무 것도하지 않지만 두 번째 문장은 예외를 일으 킵니다. 이것이 첫 번째 힌트입니다. assert는 주어진 코드 위치 (일반적으로 시작 (전제 조건) 및 함수 끝 (사후 조건))에 맞는 조건을 확인하는 데 유용합니다.
어설 션은 실제로 계약에 의한 프로그래밍과 밀접한 관련이 있으며 이는 매우 유용한 엔지니어링 관행입니다.
문서에서 :
Assert statements are a convenient way to insert debugging assertions into a program
여기에서 더 읽을 수 있습니다 : http://docs.python.org/release/2.5.2/ref/assert.html
어설 션은 버그를 잡기위한 목적으로 프로그램의 내부 상태가 프로그래머가 예상 한 상태인지 확인하는 체계적인 방법입니다. 아래 예를 참조하십시오.
>>> number = input('Enter a positive number:')
Enter a positive number:-1
>>> assert (number > 0), 'Only positive numbers are allowed!'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: Only positive numbers are allowed!
>>>
다음은 간단한 예입니다. 파일에 저장하십시오 (b.py라고합시다).
def chkassert(num):
assert type(num) == int
chkassert('a')
그리고 결과 $python b.py
Traceback (most recent call last):
File "b.py", line 5, in <module>
chkassert('a')
File "b.py", line 2, in chkassert
assert type(num) == int
AssertionError
이 assert
문장은 거의 모든 프로그래밍 언어로 존재합니다. 나중에 다른 작업의 부작용으로 발생하기보다는 원인이 분명한 프로그램의 문제를 조기에 감지하는 데 도움이됩니다. 그들은 항상 True
상태를 기대합니다 .
다음과 같은 일을 할 때 :
assert condition
프로그램에게 해당 조건을 테스트하도록 지시하고 거짓이면 즉시 오류를 트리거합니다.
파이썬에서 assert
expression 은 다음과 같습니다.
if __debug__:
if not <expression>: raise AssertionError
확장 표현식을 사용하여 선택적 메시지 를 전달할 수 있습니다 .
if __debug__:
if not (expression_1): raise AssertionError(expression_2)
파이썬 인터프리터에서 사용해보십시오.
>>> assert True # Nothing happens because the condition returns a True value.
>>> assert False # A traceback is triggered because this evaluation did not yield an expected value.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
assert
와 if
문 사이를 전환하는 것으로 여겨지는 사람들을 위해 사용하기 전에주의해야 할 몇 가지주의 사항이 있습니다 . 사용 목적 assert
은 프로그램이 조건을 확인하고 오류를 우회하는 대체 방법을 사용하는 대신 프로그램을 즉시 중지해야하는 값을 반환하는 경우입니다.
알다시피,이 assert
진술은 두 가지 조건을 사용합니다. 따라서 명확한 조언을 위해 괄호를 사용하여 괄호를 사용 하지 마십시오 . 다음과 같은 경우 :
assert (condition, message)
예:
>>> assert (1==2, 1==1)
<stdin>:1: SyntaxWarning: assertion is always true, perhaps remove parentheses?
튜플을 첫 번째 매개 변수로 나타내는 assert
with를 실행하면 (condition, message)
파이썬에서 비어 있지 않은 튜플이 항상 발생True
합니다. 그러나 문제없이 별도로 수행 할 수 있습니다.
assert (condition), "message"
예:
>>> assert (1==2), ("This condition returns a %s value.") % "False"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: This condition returns a False value.
언제 사용 assert
문 이 궁금하다면 . 실생활에서 사용되는 예를 들어 보자.
* 프로그램이 사용자가 입력 한 각 매개 변수를 제어하는 경향이있는 경우 :
def loremipsum(**kwargs):
kwargs.pop('bar') # return 0 if "bar" isn't in parameter
kwargs.setdefault('foo', type(self)) # returns `type(self)` value by default
assert (len(kwargs) == 0), "unrecognized parameter passed in %s" % ', '.join(kwargs.keys())
* 또 다른 경우는 특정 방정식에서 계수 또는 상수로 0이거나 양수가 아닌 경우 수학에 관한 것입니다.
def discount(item, percent):
price = int(item['price'] * (1.0 - percent))
print(price)
assert (0 <= price <= item['price']),\
"Discounted prices cannot be lower than 0 "\
"and they cannot be higher than the original price."
return price
* 또는 부울 구현의 간단한 예 :
def true(a, b):
assert (a == b), "False"
return 1
def false(a, b):
assert (a != b), "True"
return 0
가장 중요한 것은 assert
데이터 처리 또는 데이터 유효성 검사를 실행하기 위해 명령문에 의존하지 않는 것입니다. 이 명령문은 Python 초기화시 -O
또는 -OO
값 (각각 값 1, 2 및 0 (기본값)을 의미 함) 또는 PYTHONOPTIMIZE
환경 변수 를 사용하여 해제 할 수 있기 때문에 .
가치 1 :
* 주장은 불가능하다;
바이트 코드 파일은 .pyo
확장자 대신 .pyc
;
* sys.flags.optimize
는 1 ( True
)로 설정됩니다 .
* 및 __debug__
로 설정됩니다 False
.
가치 2 : 하나 더 물건을 비활성화
* 문서화 문자열이 비활성화되어 있습니다.
따라서이 assert
명령문을 사용하여 예상되는 데이터의 유효성을 검증하는 것은 매우 위험하므로 일부 보안 문제도 암시합니다. 그런 다음 일부 권한을 확인해야하는 경우 raise AuthError
대신 권장합니다 . 전제 조건으로,은 assert
사용자가 직접 상호 작용하지 않는 라이브러리 나 모듈의 프로그래머가 일반적으로 사용합니다.
C2 Wiki 에 간결하게 요약하면 다음과 같습니다.
어설 션은 프로그램의 특정 지점에있는 부울 식으로, 프로그램 에 버그가없는 경우 에만 적용 됩니다.
assert
명령문을 사용하여 특정 프로그램 지점에서 코드에 대한 이해를 문서화 할 수 있습니다 . 예를 들어, 입력 (사전 조건), 프로그램 상태 (불변) 또는 출력 (사후 조건)에 대한 가정 또는 보증을 문서화 할 수 있습니다.
어설 션이 실패하면 프로그램을 작성할 때 프로그램에 대한 이해가 잘못되었고 버그가 포함되어 있다는 경고입니다.
더 많은 정보를 위해, John Regehr는 Use of Assertions 에 관한 멋진 블로그 게시물을 보유하고 있으며 , 이는 Python assert
구문 에도 적용됩니다 .
Python assert 는 기본적으로 코드의 내부 자체 검사 조건을 테스트하는 디버깅 보조 도구입니다. Assert를 사용하면 코드가 불가능한 경우에 쉽게 디버깅 할 수 있습니다. 불가능한 경우를 확인하십시오.
할인 후 상품 가격을 계산하는 기능이 있다고 가정 해 보겠습니다.
def calculate_discount(price, discount):
discounted_price = price - [discount*price]
assert 0 <= discounted_price <= price
return discounted_price
여기서 discounted_price는 0보다 작거나 실제 가격보다 클 수 없습니다. 따라서 위의 조건을 위반하면 어설 션 오류가 발생하여 어설 션 오류가 발생하여 개발자가 불가능한 일이 발생했음을 식별하는 데 도움이됩니다.
그것이 도움이되기를 바랍니다 :)
assert
디버깅 컨텍스트에서 유용하지만 디버깅 컨텍스트 외부에 의존해서는 안됩니다.
내 짧은 설명은 다음과 같습니다
assert
제기 AssertionError
표현이 거짓 인 경우는 true, 그렇지 않은 경우는 바로 코드를 계속하고,이 그것이 될 것입니다 무엇이든 쉼표가 있는지 AssertionError: whatever after comma
, 그리고 코드와 같다 :raise AssertionError(whatever after comma)
이것에 관한 관련 튜토리얼 :
https://www.tutorialspoint.com/python/assertions_in_python.htm
assert
하지만 을 사용하거나 사용 하지 않을 때는 사용하지 않습니다 assert
. 또한이 있음을 지적 assert
하면 해제 할 수 있습니다 __debug__
IS가 False
유용 할 것이다.
Pycharm에서 객체 유형을 선언하는 데 assert
함께 사용 isinstance
하면 코딩하는 동안 부모 객체의 메소드 및 속성에 액세스 할 수 있으며 자동 완성됩니다.
예를 들어,하자의 말은 self.object1.object2
A는 MyClass
객체입니다.
import MyClasss
def code_it(self):
testObject = self.object1.object2 # at this point, program doesn't know that testObject is a MyClass object yet
assert isinstance(testObject , MyClasss) # now the program knows testObject is a MyClass object
testObject.do_it() # from this point on, PyCharm will be able to auto-complete when you are working on testObject
다른 답변으로 작성된 바와 같이, assert
진술은 주어진 시점에서 프로그램의 상태를 확인하는 데 사용됩니다.
관련 메시지, 괄호 또는 -O
옵션과 __debug__
상수에 대해 언급 한 내용은 반복하지 않습니다 . 의사 에게 직접 정보를 확인 하십시오. 나는 당신의 질문에 집중할 것입니다 assert
. 보다 정확하게는 언제 그리고 언제 사용하지 assert
않습니까?
이 assert
문은 프로그램을 디버깅하는 데 유용하지만 사용자 입력을 확인하지 않는 것이 좋습니다. 나는 다음과 같은 경험 법칙을 사용한다 . 이런 상황 이 발생하지 않아야한다는 것을 명심하라 . 사용자 입력이 올바르지 않을 수 있습니다 (예 : 비밀번호가 너무 짧음) . 그렇지 않은 경우 는 아닙니다 . 원의 지름이 반지름보다 두 배가 크지 않은 경우 에는 이런 일이 발생하지 않아야합니다 .
내 생각에 가장 흥미로운 assert
것은 B. Meyer가 [Object-Oriented Software Construction] ( https://www.eiffel.org/doc/eiffel/Object-Oriented_Software_Construction% 에서 설명한대로 계약 에 의한 프로그래밍에서 영감을 얻은
것입니다 .
2C_2nd_Edition
) 및 [Eiffel programming language] ( https://en.wikipedia.org/wiki/Eiffel_(programming_language) ) 에서 구현되었습니다
. assert
명령문을 사용하여 계약으로 프로그래밍을 완전히 에뮬레이트 할 수는 없지만 의도를 유지하는 것은 흥미 롭습니다.
다음은 예입니다. head
함수 를 작성해야한다고 상상해보십시오 ([ head
Haskell의 함수] (
http://www.zvon.org/other/haskell/Outputprelude/head_f.html )). 지정한 사양은 다음과 같습니다. "목록이 비어 있지 않으면 목록의 첫 번째 항목을 반환합니다." 다음 구현을 살펴보십시오.
>>> def head1(xs): return xs[0]
과
>>> def head2(xs):
... if len(xs) > 0:
... return xs[0]
... else:
... return None
(예, 이것은로 쓸 수 return xs[0] if xs else None
있지만 요점이 아닙니다) .
목록이 비어 있지 않으면 두 기능 모두 동일한 결과를 가지며이 결과는 정확합니다.
>>> head1([1, 2, 3]) == head2([1, 2, 3]) == 1
True
따라서 두 가지 구현 모두 정확합니다. 빈 목록의 헤드 항목을 가져 오려고 할 때 다릅니다.
>>> head1([])
Traceback (most recent call last):
...
IndexError: list index out of range
그러나:
>>> head2([]) is None
True
아무도이 함수에 빈 목록을 전달해서는 안되기 때문에 두 구현 모두 정확합니다 (우리는 사양을 벗어났습니다 ). 잘못된 전화이지만 전화를 걸면 어떤 일이 발생할 수 있습니다. 한 함수는 예외를 발생시키고 다른 함수는 특수 값을 반환합니다. 가장 중요한 것은 이 행동에 의존 할 수 없다는 것 입니다. xs
비어 있으면 작동합니다.
print(head2(xs))
그러나 이것은 프로그램을 중단시킵니다.
print(head1(xs))
놀라움을 피하기 위해 함수에 예기치 않은 인수를 전달할 때 알고 싶습니다. 즉, 관찰 가능한 동작이 사양이 아닌 구현에 의존하기 때문에 신뢰할 수있는 동작이 언제 신뢰할 수 없는지 알고 싶습니다. 물론 사양을 읽을 수는 있지만 프로그래머가 항상 문서를주의 깊게 읽지는 않습니다.
사양을 코드에 삽입하여 다음과 같은 효과를 얻는 방법이 있다고 상상해보십시오 head
. 올바른 (즉, 사양을 준수하는) 프로그램을 작성하는 데 큰 도움이됩니다. 그리고 그것이 assert
현장에 들어가는 곳입니다 .
>>> def head1(xs):
... assert len(xs) > 0, "The list must not be empty"
... return xs[0]
과
>>> def head2(xs):
... assert len(xs) > 0, "The list must not be empty"
... if len(xs) > 0:
... return xs[0]
... else:
... return None
이제, 우리는 :
>>> head1([])
Traceback (most recent call last):
...
AssertionError: The list must not be empty
과:
>>> head2([])
Traceback (most recent call last):
...
AssertionError: The list must not be empty
이 아닌 을 head1
던집니다 . 이 있기 때문 중요 하지 어떤 런타임 오류 : 그것은 사양의 위반을 알립니다. 경고를 원했지만 오류가 발생합니다. 다행히도 ( 옵션을 사용하여 ) 검사를 비활성화 할 수는 있지만 위험은 본인 부담입니다. 나는 그것을 할 것입니다 충돌은 정말 비싸고 최선을 다하겠습니다. 내 프로그램이 블랙홀을 통과하는 우주선에 내장되어 있다고 상상해보십시오. 어설 션을 비활성화하고 프로그램이 가능한 한 충돌하지 않을 정도로 강력하기를 바랍니다.AssertionError
IndexError
AssertionError
-O
이 예제는 전제 조건에 대한 것입니다. assert
사후 조건 (반환 값 및 / 또는 상태)과 불변 값 (클래스의 상태)을 확인 하는 데 사용할 수 있기 때문 입니다. 사후 조건과 불변량을 확인하는 assert
것은 번거로울 수 있습니다.
Eiffel만큼 세련된 것은 없지만 프로그램의 전반적인 품질을 향상시킬 수 있습니다.
요약하면,이 assert
문장은 이런 상황 이 발생하지 않아야한다는 것을 감지하는 편리한 방법 입니다. 사양 위반 (예 : 빈 목록을로 전달 head
)은 이런 상황에서 발생해서는 안되는 일류 입니다. 따라서이 assert
설명은 예상치 못한 상황을 감지하는 데 사용될 수 있지만 사양이 충족되도록 보장하는 특권이있는 방법입니다. assert
사양을 나타 내기 위해 코드에 명령문을 삽입 하면 잘못된 인수, 잘못된 반환 값, 클래스의 잘못된 상태 ...가보고되므로 프로그램의 품질이 향상되기를 바랍니다.
format : assert Expression [, arguments] assert가 명령문을 발견하면 Python은 표현식을 평가합니다. 명령문이 true가 아니면 예외가 발생합니다 (assertionError). 어설 션이 실패하면 Python은 ArgumentExpression을 AssertionError의 인수로 사용합니다. AssertionError 예외는 try-except 문을 사용하여 다른 예외와 마찬가지로 포착 및 처리 할 수 있지만 처리되지 않으면 프로그램을 종료하고 역 추적을 생성합니다. 예:
def KelvinToFahrenheit(Temperature):
assert (Temperature >= 0),"Colder than absolute zero!"
return ((Temperature-273)*1.8)+32
print KelvinToFahrenheit(273)
print int(KelvinToFahrenheit(505.78))
print KelvinToFahrenheit(-5)
위 코드를 실행하면 다음과 같은 결과가 나타납니다.
32.0
451
Traceback (most recent call last):
File "test.py", line 9, in <module>
print KelvinToFahrenheit(-5)
File "test.py", line 4, in KelvinToFahrenheit
assert (Temperature >= 0),"Colder than absolute zero!"
AssertionError: Colder than absolute zero!
def getUser(self, id, Email):
user_key = id and id or Email
assert user_key
함수 호출에서 매개 변수가 전달되도록하는 데 사용할 수 있습니다.
if not user_key: raise ValueError()
여기에서 마지막 두 단락 확인을 사용 하십시오. wiki.python.org/moin/UsingAssertionsEffectively
assert
경우 유효성 검사 중 하나가 밖으로 제거되기 때문에 입력 유효성 검사에 사용해서는 안 __debug__
이다 False
. 또한 디버그가 아닌 목적으로 어설 션을 사용하면 사람들이 결과를 포착하여 AssertionError
디버깅이 더 어려워 질 수 있습니다.
>>>this_is_very_complex_function_result = 9
>>>c = this_is_very_complex_function_result
>>>test_us = (c < 4)
>>> #first we try without assert
>>>if test_us == True:
print("YES! I am right!")
else:
print("I am Wrong, but the program still RUNS!")
I am Wrong, but the program still RUNS!
>>> #now we try with assert
>>> assert test_us
Traceback (most recent call last):
File "<pyshell#52>", line 1, in <module>
assert test_us
AssertionError
>>>
기본적으로 assert 키워드 의미는 조건이 true가 아닌 경우 assertionerror를 통해 조건이 그렇지 않으면 파이썬에서 계속된다는 것입니다.
코드 -1
a=5
b=6
assert a==b
산출:
assert a==b
AssertionError
코드 -2
a=5
b=5
assert a==b
산출:
Process finished with exit code 0
assert
이지만 을 사용하거나 사용 하지 않을 때는 답변하지 않습니다 assert
.