在GAE Python中创建一个类方法“模板”

时间:2012-01-11 05:44:08

标签: python google-app-engine

我还不熟悉python,不到一年的经验,我一直在通过在谷歌应用引擎上构建一个相当大的项目来学习它。它已经发展成为10k +代码行和html模板的庞然大物,所以我正在重构相当大一部分代码以遵循更严格的MVC架构。

我的问题是直接关于python的问题。我不知道要说出我想要构建的内容,所以我只想使用一个例子。

这是我目前用于显示视图的“基本”代码:

class MainHandler(webapp.RequestHandler):
    def get(self):
        tUser = users.get_current_user()
        tContext = {
            'user':      tUser,
            'login':     users.create_login_url(self.request.uri),
            'logout':    users.create_logout_url(self.request.uri),
        }

        #User is logged in
        if (tUser):
            #code for loading view information and adding to the context dict
            #CUSTOMIZATION GOES HERE
        else: 
            self.redirect("/")

        tmpl = os.path.join(os.path.dirname(__file__), 'logged-in.html')
        self.response.out.write(render(tmpl, tContext))

我想采用这个样板代码并以某种方式抽象它,或许可以为每个类方法预先添加/附加“可自定义”代码?

我想我可能会以某种方式使用装饰器来做这件事,但我没有在stackoverflow之外的python导师指出我正确的方向。我更倾向于使用最可能的pythonic方法,或者至少在这种情况下通常被认为是“最佳实践”。

python版本是2.7.2。

修改

注意,如果我可以使用装饰器执行此操作,那么我能够从完全不同的类和python文件调用装饰器是什么?我希望能够将我的装饰器放在一个文件中,并从其他地方引用它,所以我的代码是合理的标准化。 =)

编辑2

这是我在控制台中制作的测试代码,我必须在晚上离开,否则我会更多地改进它。但是,它似乎成功访问并修改了类的属性,这正是我认为你需要在GAE中实现这一点。

class Decorators():
@staticmethod
def BeginInit(pInFunction):
    def OutFunction1(self):
        print str(self.innerv)
        pInFunction(self)
    return OutFunction1

@staticmethod
def EndInit(pInFunction):
    def OutFunction2(self):
        self.innerv = 5
        pInFunction(self)
        print "this is test 3"
    return OutFunction2

class Test2Handler():
    innerv = 10
    @Decorators.BeginInit
    @Decorators.EndInit
    def TestPrint(self):
        print self.innerv
        print "this is test 2"

打印

10
5
this is test 2
this is test 3

1 个答案:

答案 0 :(得分:1)

您可以为请求处理程序使用基类,而不是使用装饰器,如此

class HandlerBase(webapp.RequestHandler):

    def get_context(self):
        return {}

    def get(self):
        tUser = users.get_current_user()
        tContext = {
            'user':      tUser,
            'login':     users.create_login_url(self.request.uri),
            'logout':    users.create_logout_url(self.request.uri),
        }
        # tContext holds the defaults for your context

        #User is logged in
        if (tUser):
            # if the dict returned by self.get_context() contains a key
            # that's already in tContext, tContext[key] will be overridden
            # with self.get_context()[key]
            tContext.update(self.get_context())
        else: 
            self.redirect("/")

        tmpl = os.path.join(os.path.dirname(__file__), 'logged-in.html')
        self.response.out.write(render(tmpl, tContext))


class MainHandler(HandlerBase):

    def get_context(self):
        # the contents of the following dict will be added to
        # the context in HandlerBase
        return {'greeting': 'Hi!'}