在python中将错误从类传递给渲染的html的正确方法是什么

时间:2010-02-28 18:56:15

标签: python pylons mako

我正在一个类中执行所有表单验证,并希望能够将类中的错误传递给渲染的html。我正在考虑的一种方法是创建一个全局变量“c”,它将存储所有错误并从类中设置它们,因为我仍然希望各个方法在失败时返回false。以下是一些示例代码:

class User():

def add(self):

    #Check that e-mail has been completed
    try:
        #Validate e-mail address
        if (isAddressValid(self.email)):
            c.error = 'Invalid e-mail address'
            return 0
    except NameError:
        c.error = 'No e-mail address specified'
        return 0

有更好或更好的方法吗?

感谢。

3 个答案:

答案 0 :(得分:1)

我喜欢使用字典来保存错误和警告。然后我可以在表单顶部或内联显示所有错误。我还定义了errorwarning变量,因此我可以轻松地将两者分开。

class User(object):
    def __init__(self):
        self.messages = {}

    def add(self):
        error = False
        warning = False

        #Check that name has a space
        try:
            if (self.name.find(' ') == -1):
                warning = True
                self.messages['email'] = {'type': 'warning',
                                          'msg': 'Your name has no space.'}
        except NameError:
            error = True
            self.messages['email'] = {'type': 'error',
                                      'msg': 'You have no name.'}

        #Check that e-mail has been completed
        try:
            #Validate e-mail address
            if (isAddressValid(self.email)):
                error = True
                self.messages['email'] = {'type': 'error',
                                          'msg': 'Invalid e-mail address'}
        except NameError:
            error = True
            self.messages['email'] = {'type': 'error',
                                      'msg': 'No e-mail address specified'}

        return error, warning

答案 1 :(得分:1)

是的,当然,我的建议是避免返回状态代码。

一般来说,有很多文献反对使用状态代码和全局变量来保存在Python等高级环境中处理错误的细节。
Ned Batchelder撰写了very good article on this topic;我强烈建议您阅读该页面,了解为什么异常处理通常被认为是一种优越的方法。

但是,正如我们所说的Python,传递异常和错误的官方方式是通过异常处理。期。
使用任何其他方式,将使您的代码违背对Python代码的共同期望,这意味着它将更难以阅读和维护。

答案 2 :(得分:1)

在Web应用程序的上下文中,您可以填充tmpl_context

from pylons import tmpl_context as c
from yourproject.lib.base import BaseController, render

class MyController(BaseController):
    def index(self):
        c.error = 'Invalid e-mail address'
        return render('/mytemplate.mako')

'mytemplate.mako'文件内容为:

% if c.error:
    error: ${c.error}
% endif

在通用python代码中,您可以:

返回一个元组

你可以从你的函数返回一个元组(这不是更好的方式):

class Error(Exception):
    pass

def isvalid(something):
    return False, Error("'%s' is invalid" % (something,))

示例:

ok, err = isvalid(object())
if not ok:
   print err

提出异常

如果直接调用者不应该处理函数中的错误,那么可以使用异常将错误信息传递给堆栈。

def do_stuff(something):
    if not something.isready():
       raise Error("'%s' is not ready to do stuff" % (something,))

示例:

class C(object):
    def isready(self):
        return False

def run():
    # no error handling here
    do_stuff(C()) 
    # do something else

try: run()
except Error, e:
    print e

传递回叫

def do_stuff(something, onerror=lambda err: None):
    if not something.isready():
       onerror(Error("'%s' is not ready to do stuff" % (something,)))

示例:

do = lambda: do_stuff(C(), onerror=repeat)
def repeat(err):
    """Repeat until success."""
    print err
    time.sleep(5) 
    do() # possible infinite loop 
do()