阅读bottle.py源码收获

最近拿python的单文件开源web框架bottle源码看了一下,麻雀虽小五脏俱全,看bottle源码还是能学到很多python的实践用法。

这里会陆续写一些阅读中的收获。

 

1. makelist函数

def makelist(data):
'''包装对象成为list'''
if isinstance(data, (tuple, list, set, dict)): return list(data)
elif data: return [data] # 对除去上述以外的元素生成list
else: return []

疑问:当碰到自定义的可迭代对象的时候,会返回[<iterator>]。在作者自己的代码中没有碰到这样的情况,但是我们也可以来扩展一下。

def makelist_mod(data):
'''包装任意对象成为list'''
if getattr(data, '__iter__', False): return list(data)
elif data: return [data]
else: return []

 

2. DictProperty装饰器

class DictProperty(object):
'''映射修饰后的property到owner class中的某个类似字典的attribute
(后文也用property和attribute,而不用属性,以表示区别)
'''
def __init__(self, attr, key=None, read_only=False):
self.attr, self.key, self.read_only = attr, key, read_only

# 以调用的方法使用装饰器,则被装饰的函数在__call__方法里作为参数传入
def __call__(self, func):
# 用update_wrapper的方法把func的__module__,__name__,__doc__赋给装饰后的attribute
functools.update_wrapper(self, func, updated=[])
self.getter, self.key = func, self.key or func.__name__
return self # 这个attribute是DictProperty的实例

def __get__(self, obj, cls): # 参数依次为被装饰后的实例,owner class的实例,owner class
if obj is None: return self
key, storage = self.key, getattr(obj, self.attr) # self.attr是owner class的一个attribute
if key not in storage: storage[key] = self.getter(obj)
return storage[key]

def __set__(self, obj, value):
if self.read_only: raise AttributeError("Read-Only property.")
getattr(obj, self.attr)[self.key] = value

def __delete__(self, obj):
if self.read_only: raise AttributeError("Read-Only property.")
del getattr(obj, self.attr)[self.key]

用法:

class sample(object):
def __init__(self):
self.config = {}

@DictProperty('config', 'sample.foo', read_only=True)
def foo(self):
return 'foo'

@DictProperty('config', 'sample.bar', read_only=True)
def bar(self):
return 'bar'

归纳:这个装饰器装饰后形成的property在修改后,会改变owner class中绑定的attribute。

 

3. CachedProperty装饰器

class CachedProperty(object):
'''每个实例只在第一次get的时候计算的property的值,之后存在instance的__dict__
中(当访问对象的property时,如果__dict__中有,则先返回__dict__中记录的值,如
果没有,则执行被访问property的__get__的方法。)
'''
def __init__(self, func):
self.func = func

def __get__(self, obj, cls):
if obj is None: return self
value = obj.__dict__[self.func.__name__] = self.func(obj)
return value

这个很简单,能看懂上面DictProperty,这个小case了

 

4. lazy_attribute装饰器

class lazy_attribute(object):
'''会在第一次调用的时候,把计算的结果设为owner class的attribute'''
def __init__(self, func):
functools.update_wrapper(self, func, updated=[])
self.getter = func

def __get__(self, obj, cls):
value = self.getter(cls)
setattr(cls, self.__name__, value)
return value

 

--------------------------------------------------------------------------------

 

 5. reloader实现

#coding: utf-8
import os, sys, time, subprocess, thread

# 当前文件路径
path = os.path.abspath(__file__)

# 当前文件修改时间
mtime = os.stat(path).st_mtime

# 主进程为控制器,不做功能处理
if not os.environ.get('is_child'):
    argv = [sys.executable] + sys.argv
    environ = os.environ.copy()

    # 给子进程标记,不做控制功能
    environ['is_child'] = 'true'

    # 先开一个子进程,执行程序功能
    p = subprocess.Popen(argv, env=environ)

    while True:
        if os.stat(path).st_mtime != mtime:
            mtime = os.stat(path).st_mtime
            p = subprocess.Popen(argv, env=environ)
            print 'reloaded'

        time.sleep(1)


# 程序功能部分
def main():
    print 'try to modifdy this part and save!'
    raw_input() # 模拟监听请求


# 新线程执行功能
thread.start_new_thread(main, ())

# 主线程监听结束
while True:
    if mtime < os.stat(path).st_mtime:
        sys.exit(0)

    time.sleep(1)

 

 

未完待续......















转载于:https://www.cnblogs.com/qdwang/archive/2012/03/30/2425984.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值