Is there a performance or code maintenance issue with using assert as part of the standard code instead of using it just for debugging purposes? Is assert x >= 0, 'x is less than zero' better or worse than if x < 0: raise Exception('x is less than zero') Also, is there any way to set a business rule like if x < 0 raise error that is always checked without the try/except/finally so, if at anytime throughout the code x is less than 0 an error is raised, like if you set assert x < 0 at the start of a function, anywhere within the function where x becomes less then 0 an exception is raised?
当前回答
这种方法唯一真正的错误是,很难使用断言语句产生非常描述性的异常。如果你正在寻找更简单的语法,记住你也可以这样做:
class XLessThanZeroException(Exception):
pass
def CheckX(x):
if x < 0:
raise XLessThanZeroException()
def foo(x):
CheckX(x)
#do stuff here
另一个问题是,使用assert进行正常的条件检查会使使用-O标志禁用调试断言变得困难。
其他回答
Assert是检查- 1. 有效条件, 2. 有效的表述, 3.真正的逻辑; 源代码。它不会让整个项目失败,而是会发出警报,提示源文件中有些地方不合适。
在例1中,因为变量'str'不是空的。因此不会引发任何断言或异常。
示例1:
#!/usr/bin/python
str = 'hello Python!'
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 Python!
FileName ..................... hello
FilePath ..................... C:/Python\hello.py
在例2中,var 'str'为空。因此,我们可以通过assert语句来避免用户走在错误程序前面。
示例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 没有东西会被打印出来
英语单词assert在这里的意思是发誓、肯定、宣称。它的意思不是“检查”或“应该是”。这意味着你作为一个程序员要在这里做一个宣誓声明:
# 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
如果代码是正确的,除了单事件中断、硬件故障等,任何断言都不会失败。这就是为什么程序对终端用户的行为不能受到影响。特别是,断言即使在异常的编程条件下也不能失败。这种事从来没有发生过。如果发生这种情况,程序员应该为此受到惩罚。
如前所述,当您的代码should NOT到达某个点(意味着那里存在错误)时,应该使用断言。在我看来,使用断言最有用的原因可能是不变量/前置/后置条件。在循环或函数的每次迭代的开始或结束时,这些必须为真。
例如,一个递归函数(两个独立的函数,一个处理错误的输入,另一个处理错误的代码,因为它很难与递归区分开来)。如果我忘记写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
这些循环不变量通常可以用断言表示。
当x在整个函数中小于零时,能够自动抛出错误。您可以使用类描述符。这里有一个例子:
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
assert的使用和异常的引发都与通信有关。
Assertions are statements about the correctness of code addressed at developers: An assertion in the code informs readers of the code about conditions that have to be fulfilled for the code being correct. An assertion that fails at run-time informs developers that there is a defect in the code that needs fixing. Exceptions are indications about non-typical situations that can occur at run-time but can not be resolved by the code at hand, addressed at the calling code to be handled there. The occurence of an exception does not indicate that there is a bug in the code.
最佳实践
因此,如果您将运行时发生的特定情况视为您想要通知开发人员的错误(“嗨,开发人员,这种情况表明某处存在错误,请修复代码。”),那么请使用断言。如果断言检查代码的输入参数,当输入参数违反条件时,您通常应该在文档中添加代码具有“未定义行为”。
相反,如果这种情况的出现并不是您眼中的错误,而是您认为应该由客户端代码处理的(可能很少,但可能)情况,则引发异常。引发哪种异常的情况应该是相应代码文档的一部分。
有没有演出[…]使用assert时的问题
断言的计算需要一些时间。但是,它们可以在编译时被删除。然而,这有一些后果,见下文。
有[…]使用assert的代码维护问题
Normally assertions improve the maintainability of the code, since they improve readability by making assumptions explicit and during run-time regularly verifying these assumptions. This will also help catching regressions. There is one issue, however, that needs to be kept in mind: Expressions used in assertions should have no side-effects. As mentioned above, assertions can be eliminated at compile time - which means that also the potential side-effects would disappear. This can - unintendedly - change the behaviour of the code.
推荐文章
- 如何在Flask-SQLAlchemy中按id删除记录
- 在Python中插入列表的第一个位置
- Python Pandas只合并某些列
- 如何在一行中连接两个集而不使用“|”
- 从字符串中移除前缀
- 代码结束时发出警报
- 如何在Python中按字母顺序排序字符串中的字母
- 在matplotlib中将y轴标签添加到次要y轴
- 如何消除数独方块的凹凸缺陷?
- 为什么出现这个UnboundLocalError(闭包)?
- 使用Python请求的异步请求
- 如何检查一个对象是否是python中的生成器对象?
- 如何从Python包内读取(静态)文件?
- 如何计算一个逻辑sigmoid函数在Python?
- python: SyntaxError: EOL扫描字符串文字