문제

  1. 사용과 관련하여 성능 또는 코드 유지 보수 문제가 있습니까? assert 디버깅 목적으로 만 사용하는 대신 표준 코드의 일부로?

    ~이다

    assert x >= 0, 'x is less than zero'
    

    더 낫거나 나쁘다

    if x < 0:
        raise Exception, 'x is less than zero'
    
  2. 또한 비즈니스 규칙을 설정하는 방법이 있습니까? if x < 0 raise error 그것은 항상없이 확인됩니다 try/except/finally 따라서 언제든지 코드 전체에 걸쳐 있습니다 x 0 미만입니다. 설정하면 오류가 발생합니다. assert x < 0 함수의 시작시, x 0 이하가됩니다. 예외가 제기됩니까?

도움이 되었습니까?

해결책

X가 함수 전체에서 0보다 작을 때 자동으로 오류를 던질 수 있습니다. 당신이 사용할 수있는 클래스 설명자. 예는 다음과 같습니다.

class LessThanZeroException(Exception):
    pass

class variable(object):
    def __init__(self, value=0):
        self.__x = value

    def __set__(self, obj, value):
        if value < 0:
            raise LessThanZeroException('x is less than zero')

        self.__x  = value

    def __get__(self, obj, objType):
        return self.__x

class MyClass(object):
    x = variable()

>>> m = MyClass()
>>> m.x = 10
>>> m.x -= 20
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "my.py", line 7, in __set__
    raise LessThanZeroException('x is less than zero')
LessThanZeroException: x is less than zero

다른 팁

주장은 조건을 테스트하는 데 사용되어야합니다 결코 일어나지 않아야합니다. 목적은 부패한 프로그램 상태의 경우 일찍 충돌하는 것입니다.

예외는 생각할 수있는 오류에 사용되어야하며 거의 항상 자신만의 예외 클래스를 만들어야합니다.


예를 들어, 구성 파일에서 읽을 함수를 작성하는 경우 dict, 파일의 부적절한 형식은 a ConfigurationSyntaxError, 당신은 할 수 있습니다 assert 당신이 돌아 오려고하지 않는다는 것입니다 None.


당신의 예에서, if x 사용자 인터페이스 또는 외부 소스에서 설정 한 값은 예외가 가장 좋습니다.

만약에 x 동일한 프로그램에서 자신의 코드에 의해서만 설정되며, 어설 션과 함께 가십시오.

컴파일이 최적화되면 "Assert"진술이 제거됩니다.. 그렇습니다. 성능과 기능적 차이가 모두 있습니다.

현재 코드 생성기는 컴파일 시간에 최적화를 요청할 때 Assert 문에 대한 코드를 제출하지 않습니다. - 파이썬 2.6.4 문서

사용하는 경우 assert 애플리케이션 기능을 구현 한 다음 배치를 생산에 최적화하려면 "But-it-works-in-dev"결함으로 시행됩니다.

보다 pythonoptiMize 그리고 -O -OO

네 가지 목적 assert

4 명의 동료 인 Alice, Bernd, Carl 및 Daphne과 함께 20 만 줄의 코드에서 일한다고 가정합니다. 그들은 코드를 호출하고 코드를 호출합니다.

그 다음에 assert 가지다 네 가지 역할:

  1. Alice, Bernd, Carl 및 Daphne에게 코드가 기대하는 것을 알리십시오.
    튜플 목록을 처리하는 방법이 있다고 가정하고 해당 튜플이 불변이 아닌 경우 프로그램 로직이 파손될 수 있다고 가정합니다.

    def mymethod(listOfTuples):
        assert(all(type(tp)==tuple for tp in listOfTuples))
    

    이것은 문서의 동등한 정보보다 신뢰할 수 있으며 유지 관리가 훨씬 쉽습니다.

  2. 컴퓨터에 코드가 기대하는 것을 알려줍니다.
    assert 코드의 발신자로부터 적절한 동작을 시행합니다. 코드가 Alices와 Bernd의 코드를 호출하면 assert, 프로그램이 Alices Code에서 충돌하면 Bernd는 그것이 Alice의 잘못이라고 가정 할 수 있으며, Alice는 조사하고 그것이 당신의 잘못이라고 가정 할 수도 있습니다. Bernd는 실제로 그의 것이라고 Bernd에게 말합니다. 많은 작업이 잃어 버렸습니다.
    전화를 잘못받는 사람은 누구나 당신의 잘못이 아니라 자신의 잘못이라는 것을 빨리 알 수있을 것입니다. Alice, Bernd, 그리고 당신은 모두 혜택을받습니다. 엄청난 시간을 절약합니다.

  3. 독자들에게 코드 (자신을 포함하여)에 대한 코드를 어느 시점에서 달성 한 내용을 알리십시오.
    항목 목록이 있고 각각은 깨끗하거나 (좋은) Smorsh, Trale, Gullup 또는 Twinkled (모두 허용되지 않음) 일 수 있습니다. 그것이 smorsh이라면, 그것은 미분지 여야합니다. 그것이 트랄이라면 그것은 baludoed해야합니다. 그것이 gullup이라면 트로트를해야합니다 (그리고 아마도 후속도). 반짝이는 경우 목요일을 제외하고는 다시 반짝 반짝 빛나야합니다. 당신은 아이디어를 얻습니다 : 그것은 복잡한 것입니다. 그러나 최종 결과는 모든 항목이 깨끗하다는 것입니다. 올바른 일 (TM)은 청소 루프의 효과를 다음과 같이 요약하는 것입니다.

    assert(all(entry.isClean() for entry in mylist))
    

    이 진술은 모든 사람들이 무엇을 이해하려고 노력하는 두통을 저장합니다. 바로 그거죠 멋진 루프가 달성되고 있습니다. 그리고이 사람들 중 가장 빈번한 것은 아마도 당신 자신 일 것입니다.

  4. 컴퓨터에 코드가 어느 시점에서 달성 한 것을 알려주십시오.
    트로팅 후 필요한 항목을 잊어 버린 적이 있다면 assert 당신의 하루를 구하고 당신의 코드가 Daphne의 친애하는 것을 훨씬 나중에 깨뜨리지 않도록합니다.

내 마음 속에, assert문서화 (1과 3)와 보호 (2 및 4)의 두 가지 목적은 똑같이 가치가 있습니다.
사람들에게 알리는 것도 가능합니다 바로 실수를 막을 수 있기 때문에 컴퓨터에 알리는 것보다 유용합니다. assert 어떤 경우에도 (사례 1) 많은 실수를 잡는 것을 목표로합니다.

다른 답변 외에도 스스로는 예외를 제외하고 주장하는 것만 주장합니다. 공리주의 적 관점에서 볼 때, 주장은 당신이 잡는 예외에 대한 미세한 곡물 제어가 필요할 때 적합하지 않습니다.

이 접근법에 실제로 잘못된 것은 Assert 진술을 사용하여 매우 설명적인 예외를 만드는 것이 어렵다는 것입니다. 더 간단한 구문을 찾고 있다면 기억해 ~할 수 있다 또한 다음과 같은 일을하십시오.

class XLessThanZeroException(Exception):
    pass

def CheckX(x):
    if x < 0:
        raise XLessThanZeroException()

def foo(x):
    CheckX(x)
    #do stuff here

또 다른 문제는 정상 조건 확인에 Assert를 사용하는 것이 -o 플래그를 사용하여 디버깅 어시스트를 비활성화하기가 어렵다는 것입니다.

앞에서 말했듯이, 코드가 포인트에 도달하지 않아야 할 때 주장을 사용해야합니다. 즉, 버그가 있음을 의미합니다. 아마도 내가 주장을 사용하는 가장 유용한 이유는 불변/사전/사후 조건 일 것입니다. 이들은 루프 또는 함수의 각 반복의 시작 또는 끝에 사실이어야 할 것입니다.

예를 들어, 재귀 함수 (2 개의 분리 함수가 있으므로 1은 잘못된 입력을 처리하고 다른 하나는 잘못된 코드를 처리하므로 재귀와 구별하기가 어렵습니다). IF 문을 쓰는 것을 잊어 버린 경우, 무엇이 잘못되었는지를 알 수 있습니다.

def SumToN(n):
    if n <= 0:
        raise ValueError, "N must be greater than or equal to 0"
    else:
        return RecursiveSum(n)

def RecursiveSum(n):
    #precondition: n >= 0
    assert(n >= 0)
    if n == 0:
        return 0
    return RecursiveSum(n - 1) + n
    #postcondition: returned sum of 1 to n

이러한 루프 불변량은 종종 주장으로 표현 될 수 있습니다.

영어 단어 주장하다 다음은 의미에서 사용됩니다 욕을 하다, 확인, Avow. 의미가 아닙니다 "확인하다" 또는 "해야한다". 그것은 의미합니다 코더가 만들고 있습니다 맹세 진술 여기:

# I solemnly swear that here I will tell the truth, the whole truth, 
# and nothing but the truth, under pains and penalties of perjury, so help me FSM
assert answer == 42

코드가 올바른 경우 배가 단일 이벤트 업셋, 하드웨어 고장 등, 아무런 주장도 실패하지 않을 것입니다. 그렇기 때문에 최종 사용자에게 프로그램의 동작이 영향을받지 않아야합니다. 특히, 어설 션은 실패 할 수 없습니다 탁월한 프로그래밍 조건. 그냥 일어나지 않습니다. 발생하면 프로그래머는이를 위해 zapped해야합니다.

~이다 성능 문제가 있습니까?

  • 기억하십시오 "빨리 작동하기 전에 먼저 작동하게합니다".
    모든 프로그램의 몇 %가 일반적으로 속도와 관련이 있습니다. 항상 시작하거나 단순화 할 수 있습니다 assert 그것이 성능 문제로 판명된다면, 대부분은 결코 결코 그렇게하지 않을 것입니다.

  • 실용적이어야합니다:
    튜플의 비어 있지 않은 목록을 처리하는 방법이 있다고 가정하고 해당 튜플이 불변이 아닌 경우 프로그램 논리가 파손됩니다. 당신은 다음을 작성해야합니다 :

    def mymethod(listOfTuples):
        assert(all(type(tp)==tuple for tp in listOfTuples))
    

    목록이 10 개의 항목 길이가되면 괜찮을 것입니다. 그러나 백만 개의 항목이 있으면 문제가 될 수 있습니다. 그러나이 귀중한 점검을 완전히 버리지 않고 단순히 다운 그레이드 할 수 있습니다.

    def mymethod(listOfTuples):
        assert(type(listOfTuples[0])==tuple)  # in fact _all_ must be tuples!
    

    저렴하지만 대부분의 실제 어쨌든 프로그램 오류.

Jboss라는 프레임 워크가 있습니다 침포 비즈니스 규칙을 주장하기 위해 런타임 모니터링을하는 Java의 경우 질문의 두 번째 부분에 응답합니다. 그러나 파이썬에 대한 프레임 워크가 있는지 확실하지 않습니다.

주장은 확인하는 것입니다.
1. 유효한 조건,
2. 유효한 진술,
3. 진정한 논리;
소스 코드. 전체 프로젝트에 실패하는 대신 소스 파일에서 무언가가 적절하지 않다는 경보를 제공합니다.

예 1에서, 변수 'str'는 nul이 아니기 때문에. 따라서 어떠한 주장이나 예외도 제기되지 않습니다.

Example 1:

#!/usr/bin/python

str = 'hello Pyhton!'
strNull = 'string is Null'

if __debug__:
    if not str: raise AssertionError(strNull)
print str

if __debug__:
    print 'FileName '.ljust(30,'.'),(__name__)
    print 'FilePath '.ljust(30,'.'),(__file__)


------------------------------------------------------

Output:
hello Pyhton!
FileName ..................... hello
FilePath ..................... C:/Python\hello.py

예 2에서, var 'str'는 nul입니다. 그래서 우리는 사용자가 결함이있는 프로그램보다 앞서 나가는 것을 저장하고 있습니다. 주장하다 성명.

Example 2:

#!/usr/bin/python

str = ''
strNull = 'NULL String'

if __debug__:
    if not str: raise AssertionError(strNull)
print str

if __debug__:
    print 'FileName '.ljust(30,'.'),(__name__)
    print 'FilePath '.ljust(30,'.'),(__file__)


------------------------------------------------------

Output:
AssertionError: NULL String

우리가 디버그를 원하지 않는 순간 소스 코드에서 어설 션 문제를 실현했습니다. 최적화 플래그를 비활성화합니다

python -o assertstatement.py
아무것도 인쇄 할 수 없습니다

PTVS, Pycharm, Wing과 같은 IDE에서 assert isinstance() 명령문은 불분명 한 객체에 대한 코드 완료를 가능하게하는 데 사용될 수 있습니다.

의존하는 레거시 코드를 다루는 경우 assert 그래도 제대로 작동합니다 그것은 안됩니다, 그런 다음 다음 코드를 추가하는 것은 리팩터에 시간을 찾을 때까지 빠른 수정입니다.

try:
    assert False
    raise Exception('Python Assertions are not working. This tool relies on Python Assertions to do its job. Possible causes are running with the "-O" flag or running a precompiled (".pyo" or ".pyc") module.')
except AssertionError:
    pass
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top