首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > perl python >

《在路下 …》 写代码也需要一点演技 – python2.6 的 class decorator

2012-07-01 
《在路上 …》 写代码也需要一点演技 – python2.6 的 class decorator写通用的回复类, 原本打算做成一个独立

《在路上 …》 写代码也需要一点演技 – python2.6 的 class decorator

写通用的回复类, 原本打算做成一个独立的基类


class ReplyBase(object):

?? ?_REPLY_REALTED_CLS = None ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

?? ?_REPLY_CLS = None ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

?? ?mc_reply_id_by_rid = McLimitA( ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

?? ? ? ?"ReplyIdBy%sId:%%s"%_REPLY_RCLS.Meta.table.title(), ? ? ? ? ? ? ? ? ? ? ? ??

?? ? ? ?128 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

?? ?)

?? ?...


写下来以后, 忽然想到 ? ? ? ?


"ReplyIdBy%sId:%%s"%_REPLY_RCLS.Meta.table.title(), ? ? ? ? ? ? ? ? ? ? ? ??


在基类定义的时候就被确定了, 不好搞


这样下去就只有用Meta Class


不过正如 洪教授 所言 ( http://www.infoq.com/cn/interviews/douban-hqn )


Meta Class 是种黑魔法, 正派人士都很畏惧它.


虽然有部YY小说, 标题叫做"魔本是道", 不过这也就是纯属意淫, 估计连本实体书都没有.


正如我昨天说过的 做人需要一点演技( http://www.douban.com/note/101804926/ )


写代码也不能太暴露内心的邪恶念头.


decorator, 正如其名, 装饰器, "装"是核心词, 是我圣教中人, 行走江湖必备的技能.?


好吧, 过去我常常以"张教主"自诩, 不过一晃也有很多年没进行官方的正式声明了.?


江湖儿女江湖老,昏昏灯火忆平生.


言归正传, 先来做一个小实验, 用函数动态添加一个基类


class C(object):

?? ?def x(self):

?? ? ? ?return self.__class__


class B(object):

?? ?pass


class A(B):

?? ?pass


def main():

?? ?print "A.__bases__ before", A.__bases__

?? ?A.__bases__ = tuple(list(A.__bases__)+[C, ])

?? ?print "A.__bases__ after", A.__bases__

?? ?print "A().x()", A().x()


输出是


A.__bases__ before (<class '__main__.B'>,)

A.__bases__ after (<class '__main__.B'>, <class '__main__.C'>)

A().x() <class '__main__.A'>


人体试验很成功, 我很开心


当然, 我这里有些细节懒得交代了, 我是工科生, 不是理科生, 我只追求可以work的solution, 不考究背后theory. 何况我本科文凭中还有"医学"两个字符.


医学是只看结果不问过程的.


不过, 如果你遇到什么问题, 可以从这里开始探索 http://blog.donews.com/limodou/archive/2005/01/06/227676.aspx


说了这么多, 还是直接上代码吧, 代码是很无趣. 就像武功秘籍一样.


找秘籍的人永远很多, 炼成的永远很少.


这还是精简演示版, 很多接口没做.


如果说Meta Class是基因改造, ?class decorator就像是整容手术了. 下面正式开工


=================================================


#!/usr/bin/env python

#coding:utf-8

from init_db import McModel, McCacheA, McCache, Model, mc, cursor_by_table, McLimitA

from const.man import STATE_DEL, STATE_APPLY, STATE_ACTIVE, STATE_BAN


class ReplyMixin(object):

?? ?def new_reply(self, man_id, txt, state=STATE_ACTIVE):

?? ? ? ?rid = self.id

?? ? ? ?self.reply_count += 1

?? ? ? ?self.save()

?? ? ? ?s = self._REPLY_CLS(rid=rid, man_id=man_id, state=state)

?? ? ? ?s.txt = txt

?? ? ? ?s.save()

?? ? ? ?self.mc_reply_id_by_rid.delete(rid)

?? ? ? ?return s



?? ?def reply_list(self, offset, limit):

?? ? ? ?return self._REPLY_CLS.mc_get_list(

?? ? ? ? ? ?self.reply_id_list(offset, limit)

?? ? ? ?)


def mixin_reply(reply_cls):

?? ?"""

@mixin_reply(XxxReply)

class Xxx(McModel):

?? ?pass

?? ?"""

?? ?def _(cls):

?? ? ? ?cls.__bases__ = tuple(list(cls.__bases__)+[ReplyMixin, ])

?? ? ? ?cls.mc_reply_id_by_rid = McLimitA(

?? ? ? ? ? ?"ReplyIdBy%sId#%%s"%cls.Meta.table.title(),

?? ? ? ? ? ?128

?? ? ? ?)

?? ? ? ?cls._REPLY_CLS = reply_cls

?? ? ? ?cls.reply_id_list = cls.mc_reply_id_by_rid("{self.id}")(

?? ? ? ? ? ?reply_id_list

?? ? ? ?)

?? ? ? ?return cls

?? ?return _


def reply_id_list(self, offset, limit):

?? ?c = self._REPLY_CLS.raw_sql(

?? ? ? ?"select id from " +

?? ? ? ?self._REPLY_CLS.Meta.table +

?? ? ? ?" where rid=%s and state>%s order by create_time limit %s offset %s",

?? ? ? ?self.id, STATE_APPLY, limit, offset

?? ?)

?? ?return [i for i, in c.fetchall()]




=============================


同时为了统一管理, 迁移原来的一些reply函数到新代码上, 但是保留原接口


=============================


--- mysite/model/review.py(revision 3071)

+++ mysite/model/review.py(working copy)


+from reply import mixin_reply

?

?

?class ReviewReply(McModel):

?? ? pass

?

+@mixin_reply(ReviewReply)

class Review(McModel):

?? ?txt = review_txt.property

?

?def review_reply_by_review_id(id, offset, limit):

- ? ?return ReviewReply.mc_get_list(

- ? ? ? ?review_reply_id_by_review_id(id, offset, limit)

+ ? ?return Review(id).reply_list(

+ ? ? ? ?offset, limit

?? ? )

?

?def review_reply_new(review_id, man_id, txt, state=STATE_ACTIVE):

?? ? r = Review.mc_get(review_id)

- ? ?if r:

- ? ? ? ?r.reply_count += 1

- ? ? ? ?r.save()

- ? ? ? ?s = ReviewReply(rid=review_id, man_id=man_id, state=state)

- ? ? ? ?s.txt = txt

- ? ? ? ?s.save()

- ? ? ? ?mc_review_reply_id_by_review_id.delete(s.id)

- ? ? ? ?return s

+ ? ?return r.new_reply(man_id,txt,state)




订阅到Google分享到 豆瓣BuzzTwitter人人新浪文章同步自 http://kanrss.com/~onway/t/110
同步程序见 这里
作者 张沈鹏


热点排行