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标志禁用调试断言变得困难。
其他回答
断言应该用于测试不应该发生的情况。目的是在程序状态损坏的情况下尽早崩溃。
异常应该用于可能发生的错误,并且几乎总是应该创建自己的Exception类。
例如,如果您正在编写一个从配置文件读取到dict的函数,那么文件中的不当格式将引发ConfigurationSyntaxError,而您可以断言您不会返回None。
在您的示例中,如果x是通过用户界面或外部源设置的值,则最好使用异常。
如果x只是在同一个程序中由您自己的代码设置的,则使用断言。
这种方法唯一真正的错误是,很难使用断言语句产生非常描述性的异常。如果你正在寻找更简单的语法,记住你也可以这样做:
class XLessThanZeroException(Exception):
pass
def CheckX(x):
if x < 0:
raise XLessThanZeroException()
def foo(x):
CheckX(x)
#do stuff here
另一个问题是,使用assert进行正常的条件检查会使使用-O标志禁用调试断言变得困难。
"assert"语句在编译优化时被删除。所以,是的,它们在性能和功能上都有差异。
在编译时请求优化时,当前代码生成器不会为assert语句生成代码。Python 3 Docs
如果您使用assert来实现应用程序功能,然后优化部署到生产环境,那么您将受到“但它在开发中有效”缺陷的困扰。
参见PYTHONOPTIMIZE和-O -OO
是否存在性能问题?
Please remember to "make it work first before you make it work fast". Very few percent of any program are usually relevant for its speed. You can always kick out or simplify an assert if it ever proves to be a performance problem -- and most of them never will. Be pragmatic: Assume you have a method that processes a non-empty list of tuples and the program logic will break if those tuples are not immutable. You should write: def mymethod(listOfTuples): assert(all(type(tp)==tuple for tp in listOfTuples)) This is probably fine if your lists tend to be ten entries long, but it can become a problem if they have a million entries. But rather than discarding this valuable check entirely you could simply downgrade it to def mymethod(listOfTuples): assert(type(listOfTuples[0])==tuple) # in fact _all_ must be tuples! which is cheap but will likely catch most of the actual program errors anyway.
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 没有东西会被打印出来
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录