提案:运行时验证语句 [英] Proposal: runtime validation statement

查看:87
本文介绍了提案:运行时验证语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常发现自己写的东西像


#compute frob函数,x必须是非负的

x = read_input_data()

断言x> = 0,x#误用断言声明

frob = sqrt(x)+ x / 2。 + 3.


这是不正确的,因为断言语句应该是

验证程序本身的逻辑一致性,而不是输入

数据。因此,例如,当您使用优化进行编译时,断言

语句变为无操作。然而,通常需要尽可能地验证输入
验证输入,并且提出异常通常是对坏数据做正确的事情。像


类的函数ValidationError(异常):传递

def _validate(cond,message):

如果不是cond:提出ValidationError,消息


会照顾它,当然,添加

特殊声明(如


验证x> = 0,(x,一定不能为负)


与assert完全相同但引发了不同的异常并且

永远不会被优化掉。但是同样可以说打印

语句(使用sys.stdout.write或打印函数代替)和

,这与加法运算符有关(使用" x - ( - y)而不是x + y,

bool类型(使用1和0而不是True和False)等等。


我们必须得出结论,选择语言

支持的语句不仅仅是让事情成为可能的事情,而且还要指导

指导常见习语应该是什么。使用用户定义的

函数来检查输入意味着更多特定于程序的事情要记住(函数本身和它引发的异常类),

使代码混乱,等等。所以我觉得像上面的验证

语句(可能有一些不同的关键字)在

Pythonic精神,应考虑即将发布。


想法?

解决方案

Paul Rubin写道:

我经常发现自己写的东西像

#compute frob函数,x必须是非负的
x = read_input_data()
断言x> = 0,x#误用断言声明
frob = sqrt(x)+ x / 2。 + 3.

这是不正确的,因为assert语句应该验证程序本身的逻辑一致性,而不是输入数据。因此,例如,当您使用优化进行编译时,断言
语句将变为无操作。然而,通常需要尽可能地验证输入,并且提出异常通常是对坏数据做正确的事情。类似ValidationError(异常)的函数:传递
def _validate(cond,message):
如果不是cond:raise ValidationError,message

当然,要处理它,所以添加

验证x> = 0,(x,一定不能为负等特殊声明有点多余。 )

与assert完全一样,但引发了一个不同的异常,并且从未优化过。但是同样可以说print
语句(使用sys.stdout.write或打印函数代替)和
这个加法运算符(使用x - (-y))。而不是x + y),
bool类型(使用1和0而不是True和False)等等。

我们必须得出结论,选择语言的语句
支持不仅仅是让事情成为可能的问题,而且还是指导常见习语应该是什么。使用用户定义的
函数来检查输入意味着要记住更多特定于程序的事物(函数本身和它引发的异常类),
使代码混乱等等。所以我觉得像上面这样的验证声明(可能带有一些不同的关键词)属于Pythonic精神,应该考虑进行一些即将发布的声明。 />
想法?




我使用assert来保护我的软件,即捕获编程

错误,例如抓住我以错误方式调用方法的情况。如果

这也可以在生产协议下发生,那么这是用户错误,

不是编程错误。


因此,我使用raise来保护我的软件免受用户错误的影响。


您的样本似乎是后者的情况,即您必须写一些

一些无论如何都要处理异常。在您的代码中的任何地方发出错误消息

可能不是您真正想要的。


亲切的问候

Franz GEIGER


Paul Rubin写道:

[snip]

经常与坏数据做对的事情。类似ValidationError(异常)的函数:传递
def _validate(cond,message):
如果不是cond:raise ValidationError,message

当然,要处理它,所以添加

验证x> = 0,(x,一定不能为负等特殊声明有点多余。 )

与assert完全一样,但引发了一个不同的异常,并且从未优化过。但是同样可以说print
语句(使用sys.stdout.write或打印函数代替)和
这个加法运算符(使用x - (-y))。而不是x + y),
bool类型(使用1和0而不是True和False)等等。

我们必须得出结论,选择语言的语句
支持不仅仅是让事情成为可能的问题,而且还是指导常见习语应该是什么。使用用户定义的
函数来检查输入意味着要记住更多特定于程序的事物(函数本身和它引发的异常类),
使代码混乱等等。所以我觉得像上面这样的验证声明(可能带有一些不同的关键词)属于Pythonic精神,应该考虑进行一些即将发布的声明。 />
想法?




同意!


我通常最终继承子类化Exception并编写验证函数

就像你上面所示。起初我喜欢这样一个事实:一个模块抛出了一个特定的异常系列异常系列,可以在下游捕获,

但是在使用这种方法一段时间后我已经得出了

的结论,绝大多数情况下抛出的异常是通用的ValidationError的
。各种各样的,并且以模块特定的方式定义

不会增加任何价值。通过扩展,验证

函数本身不会增加任何价值,只会令人讨厌。


此外,开发人员定义的函数并不突出以及

语句 - 一个声明将它与普通函数调用区分开来

正在做实际工作来解决手头的问题 - 而且它已经<语法高亮的编辑器也很容易对它进行不同的着色。


IMO''validate''对于关键字来说并不是一个太糟糕的选择。排序很长,但是很快就可以输入



-Dave


> >>>> "保罗" == Paul Rubin< http://ph****@NOSPAM.invalid>写道:


Paul>当然,照顾它,所以它有点多余。

Paul>添加一个特殊的声明,如


Paul>验证x> = 0,(x,一定不能为负)


Paul>它的作用与断言完全相同但提出了不同的保证价格。保罗>异常,永远不会被优化掉。但同样可以是

Paul>说到print语句(使用sys.stdout.write或打印

Paul>函数),就此而言,加法运算符

Paul> (使用x - ( - y)而不是x + y),bool类型(使用1和0

Paul>而不是True和False)等等。


是的,而我(以及其他许多人,我觉得)认为打印声明是一种疣语言的b $ b。让我们不再做这些了......太糟糕了,所以

被广泛使用它不能被弃用。


保罗>指导常见习语应该是什么。使用

Paul>用户定义的函数检查输入意味着更多的

Paul>程序特定的事情要记住(函数本身和

Paul>它引发的异常类),使代码混乱等等。

Paul>所以我开始觉得验证了声明(也许

保罗>与一些不同的关键词)如上所述是在

Paul> Pythonic精神应该考虑一些

Paul>即将发布。


任何特定原因都不能使它成为内置函数而不是

语句?我不介意验证函数,也可以验证参数的数据类型,然后可以用于

代码完成帮助和类型推断。因为当真实时,我们不知道

。类型声明发生。期望他们达到2.5是

可能有点过于乐观;-)。


def a(x,y):

validate((x,int),(y,str),x> int(y))


(验证每个元组用isinstance检查(t [0],t [ 1]),每个arg到

验证pythonic falsehoos sense2中的false都没有通过

验证)


在此之类的官方之前,帮助工具和IDE不能使用类型信息。


-

Ville Vainio http://tinyurl.com/2prnb

I frequently find myself writing stuff like

# compute frob function, x has to be nonnegative
x = read_input_data()
assert x >= 0, x # mis-use of "assert" statement
frob = sqrt(x) + x/2. + 3.

This is not really correct because the assert statement is supposed to
validate the logical consistency of the program itself, not the input
data. So, for example, when you compile with optimization on, assert
statements become no-ops. And yet, it''s generally desirable to
validate input whenever you can, and raising an exception is
frequently the right thing to do with bad data. A function like

class ValidationError(Exception): pass
def _validate(cond, message):
if not cond: raise ValidationError, message

takes care of it, of course, so it''s slightly redundant to add a
special statement like

validate x >= 0, (x, "must not be negative")

which works exactly like assert but raises a different exception and
is never optimized away. But the same can be said of the print
statement (use sys.stdout.write or a print function instead) and for
that matter the addition operator (use "x - (-y)" instead of x+y), the
bool type (use 1 and 0 instead of True and False), etc.

We have to conclude that choosing what statements the language
supports is not just a matter of making things possible, but also of
steering what the common idioms should be. Using a user-defined
function to check input means a couple more program-specific things to
remember (the function itself and the exception class it raises),
clutters up the code, etc. And so I''ve come to feel that a "validate"
statement (maybe with some different keyword) like the above is in the
Pythonic spirit and should be considered for some forthcoming release.

Thoughts?

解决方案

Paul Rubin wrote:

I frequently find myself writing stuff like

# compute frob function, x has to be nonnegative
x = read_input_data()
assert x >= 0, x # mis-use of "assert" statement
frob = sqrt(x) + x/2. + 3.

This is not really correct because the assert statement is supposed to
validate the logical consistency of the program itself, not the input
data. So, for example, when you compile with optimization on, assert
statements become no-ops. And yet, it''s generally desirable to
validate input whenever you can, and raising an exception is
frequently the right thing to do with bad data. A function like

class ValidationError(Exception): pass
def _validate(cond, message):
if not cond: raise ValidationError, message

takes care of it, of course, so it''s slightly redundant to add a
special statement like

validate x >= 0, (x, "must not be negative")

which works exactly like assert but raises a different exception and
is never optimized away. But the same can be said of the print
statement (use sys.stdout.write or a print function instead) and for
that matter the addition operator (use "x - (-y)" instead of x+y), the
bool type (use 1 and 0 instead of True and False), etc.

We have to conclude that choosing what statements the language
supports is not just a matter of making things possible, but also of
steering what the common idioms should be. Using a user-defined
function to check input means a couple more program-specific things to
remember (the function itself and the exception class it raises),
clutters up the code, etc. And so I''ve come to feel that a "validate"
statement (maybe with some different keyword) like the above is in the
Pythonic spirit and should be considered for some forthcoming release.

Thoughts?



I use assert to protect my software from me, i.e. to catch programming
errors, e.g. to catch cases where I called a method the wrong way. If
this can happen under production consitions too, then it''s a user error,
not a programming error.

So, I use raise to protect my software from user errors.

Your sample seems to be a case of the latter, i.e. you have to write
some sort of exception handling anyway. Issuing an error message
anywhere in your code might not be what you really want.

Kind regards
Franz GEIGER


Paul Rubin wrote:
[snip]

frequently the right thing to do with bad data. A function like

class ValidationError(Exception): pass
def _validate(cond, message):
if not cond: raise ValidationError, message

takes care of it, of course, so it''s slightly redundant to add a
special statement like

validate x >= 0, (x, "must not be negative")

which works exactly like assert but raises a different exception and
is never optimized away. But the same can be said of the print
statement (use sys.stdout.write or a print function instead) and for
that matter the addition operator (use "x - (-y)" instead of x+y), the
bool type (use 1 and 0 instead of True and False), etc.

We have to conclude that choosing what statements the language
supports is not just a matter of making things possible, but also of
steering what the common idioms should be. Using a user-defined
function to check input means a couple more program-specific things to
remember (the function itself and the exception class it raises),
clutters up the code, etc. And so I''ve come to feel that a "validate"
statement (maybe with some different keyword) like the above is in the
Pythonic spirit and should be considered for some forthcoming release.

Thoughts?



Agreed!

I usually end up subclassing Exception and writing a validation function
like you show above. At first I liked the fact that a module threw a
module-specific family of exceptions that could be caught downstream,
but after having used this approach for some time I''ve come to the
conclusion that the vast majority of the time the exceptions thrown are
of the generic "ValidationError" variety, and that having them defined
in a module-specific way added no value. By extension, the validation
function itself adds no value and is just a nuisance.

Also, a developer-defined function doesn''t stand out as well as a
statement would - a statement sets it apart from normal function calls
which are doing the actual work to solve the problem at hand - and it''d
be easy for syntax-highlighting editors to color it differently too.

IMO ''validate'' isn''t too bad a choice for a keyword. Sorta long but it''s
quick to type.

-Dave


>>>>> "Paul" == Paul Rubin <http://ph****@NOSPAM.invalid> writes:

Paul> takes care of it, of course, so it''s slightly redundant to
Paul> add a special statement like

Paul> validate x >= 0, (x, "must not be negative")

Paul> which works exactly like assert but raises a different
Paul> exception and is never optimized away. But the same can be
Paul> said of the print statement (use sys.stdout.write or a print
Paul> function instead) and for that matter the addition operator
Paul> (use "x - (-y)" instead of x+y), the bool type (use 1 and 0
Paul> instead of True and False), etc.

Yes, and I (and many others, I feel) consider print statement a wart
in the language. Let''s not make any more of these... Too bad it''s so
widely used it can''t be right out deprecated.

Paul> steering what the common idioms should be. Using a
Paul> user-defined function to check input means a couple more
Paul> program-specific things to remember (the function itself and
Paul> the exception class it raises), clutters up the code, etc.
Paul> And so I''ve come to feel that a "validate" statement (maybe
Paul> with some different keyword) like the above is in the
Paul> Pythonic spirit and should be considered for some
Paul> forthcoming release.

Any specific reason not to make it a builtin function instead of
statement? I wouldn''t mind a validation function that could also
verify the data types of the arguments, which could then be used for
code completion assistance and type inference... Since we don''t know
when a "real" type declarations happen. Expecting them to hit 2.5 is
probably a bit too optimistic ;-).

def a(x,y):
validate((x,int), (y,str), x > int(y))

(validate checks every tuple with isinstance(t[0],t[1]), every arg to
validate that is "false" in the pythonic falsehoos sense2 fails the
validation)

Before something like that goes "official", help tools and IDEs can''t
use the type information.

--
Ville Vainio http://tinyurl.com/2prnb


这篇关于提案:运行时验证语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆