当前位置: 首页 > news >正文

烟台网站开发多少钱张家港网站建设哪家好

烟台网站开发多少钱,张家港网站建设哪家好,seo包年优化,百度找不到 网站Python 的 Decorator在使用上和Java/C#的Annotation很相似#xff0c;就是在方法名前面加一个XXX注解来为这个方法装饰一些东西。但是#xff0c;Java/C#的Annotation也很让人望而却步#xff0c;太TMD的复杂了#xff0c;你要玩它#xff0c;你需要了解一堆Annotation的类…Python 的 Decorator在使用上和Java/C#的Annotation很相似就是在方法名前面加一个XXX注解来为这个方法装饰一些东西。但是Java/C#的Annotation也很让人望而却步太TMD的复杂了你要玩它你需要了解一堆Annotation的类库文档让人感觉就是在学另外一门语言。而Python使用了一种相对于Decorator Pattern和Annotation来说非常优雅的方法这种方法不需要你去掌握什么复杂的OO模型或是Annotation的各种类库规定完全就是语言层面的玩法一种函数式编程的技巧。如果你看过本站的《函数式编程》你一定会为函数式编程的那种“描述你想干什么而不是描述你要怎么去实现”的编程方式感到畅快。(如果你不了解函数式编程那在读本文之前还请你移步去看看《函数式编程》) 好了我们先来点感性认识看一个Python修饰器的Hello World的代码。Hello World下面是代码文件名hello.pydef hello(fn):def wrapper():print hello, %s % fn.__name__fn()print goodby, %s % fn.__name__return wrapperhellodef foo():print i am foofoo()当你运行代码你会看到如下输出[chenahochenhao-air]$ python hello.pyhello, fooi am foogoodby, foo你可以看到如下的东西1)函数foo前面有个hello的“注解”hello就是我们前面定义的函数hello2)在hello函数中其需要一个fn的参数(这就用来做回调的函数)3)hello函数中返回了一个inner函数wrapper这个wrapper函数回调了传进来的fn并在回调前后加了两条语句。Decorator 的本质对于Python的这个注解语法糖- Syntactic Sugar 来说当你在用某个decorator来修饰某个函数func时如下所示:decoratordef func():pass其解释器会解释成下面这样的语句func decorator(func)尼玛这不就是把一个函数当参数传到另一个函数中然后再回调吗是的但是我们需要注意那里还有一个赋值语句把decorator这个函数的返回值赋值回了原来的func。 根据《函数式编程》中的first class functions中的定义的你可以把函数当成变量来使用所以decorator必需得返回了一个函数出来给func这就是所谓的higher order function 高阶函数不然后面当func()调用的时候就会出错。 就我们上面那个hello.py里的例子来说hellodef foo():print i am foo被解释成了foo hello(foo)是的这是一条语句而且还被执行了。你如果不信的话你可以写这样的程序来试试看def fuck(fn):print fuck %s! % fn.__name__[::-1].upper()fuckdef wfg():pass没了就上面这段代码没有调用wfg()的语句你会发现 fuck函数被调用了而且还很NB地输出了我们每个人的心声再回到我们hello.py的那个例子我们可以看到hello(foo)返回了wrapper()函数所以foo其实变成了wrapper的一个变量而后面的foo()执行其实变成了wrapper()。知道这点本质当你看到有多个decorator或是带参数的decorator你也就不会害怕了。比如多个decoratordecorator_onedecorator_twodef func():pass相当于func decorator_one(decorator_two(func))比如带参数的decoratordecorator(arg1, arg2)def func():pass相当于func decorator(arg1,arg2)(func)这意味着decorator(arg1, arg2)这个函数需要返回一个“真正的decorator”。带参数及多个Decrorator我们来看一个有点意义的例子html.pydef makeHtmlTag(tag, args, *kwds):def real_decorator(fn):css_class class{0}.format(kwds[css_class])if css_class in kwds else def wrapped(*args, **kwds):return fn(*args, **kwds) tagreturn wrappedreturn real_decoratormakeHtmlTag(tagb, css_classbold_css)makeHtmlTag(tagi, css_classitalic_css)def hello():return hello worldprint hello()输出hello world在上面这个例子中我们可以看到makeHtmlTag有两个参数。所以为了让 hello makeHtmlTag(arg1, arg2)(hello) 成功makeHtmlTag 必需返回一个decorator(这就是为什么我们在makeHtmlTag中加入了real_decorator()的原因)这样一来我们就可以进入到 decorator 的逻辑中去了—— decorator得返回一个wrapperwrapper里回调hello。看似那个makeHtmlTag() 写得层层叠叠但是已经了解了本质的我们觉得写得很自然。你看Python的Decorator就是这么简单没有什么复杂的东西你也不需要了解过多的东西使用起来就是那么自然、体贴、干爽、透气独有的速效凹道和完美的吸收轨迹让你再也不用为每个月的那几天感到焦虑和不安再加上贴心的护翼设计量多也不用当心。对不起我调皮了。什么你觉得上面那个带参数的Decorator的函数嵌套太多了你受不了。好吧没事我们看看下面的方法。class式的 Decorator首先先得说一下decorator的class方式还是看个示例class myDecorator(object):def __init__(self, fn):print inside myDecorator.__init__()self.fn fndef __call__(self):self.fn()print inside myDecorator.__call__()myDecoratordef aFunction():print inside aFunction()print Finished decorating aFunction()aFunction()输出inside myDecorator.__init__()Finished decorating aFunction()inside aFunction()inside myDecorator.__call__()上面这个示例展示了用类的方式声明一个decorator。我们可以看到这个类中有两个成员1)一个是__init__()这个方法是在我们给某个函数decorator时被调用所以需要有一个fn的参数也就是被decorator的函数。2)一个是__call__()这个方法是在我们调用被decorator函数时被调用的。上面输出可以看到整个程序的执行顺序。这看上去要比“函数式”的方式更易读一些。下面我们来看看用类的方式来重写上面的html.py的代码html.pyclass makeHtmlTagClass(object):def __init__(self, tag, css_class):self._tag tagself._css_class class{0}.format(css_class)if css_class ! else def __call__(self, fn):def wrapped(*args, **kwargs):return fn(*args, **kwargs) self._tag return wrappedmakeHtmlTagClass(tagb, css_classbold_css)makeHtmlTagClass(tagi, css_classitalic_css)def hello(name):return Hello, {}.format(name)print hello(Hao Chen)上面这段代码中我们需要注意这几点1)如果decorator有参数的话__init__() 成员就不能传入fn了而fn是在__call__的时候传入的。2)这段代码还展示了 wrapped(args, *kwargs) 这种方式来传递被decorator函数的参数。(其中args是一个参数列表kwargs是参数dict具体的细节请参考Python的文档或是StackOverflow的这个问题这里就不展开了)用Decorator设置函数的调用参数你有三种方法可以干这个事第一种通过 **kwargs这种方法decorator会在kwargs中注入参数。def decorate_A(function):def wrap_function(*args, **kwargs):kwargs[str] Hello!return function(*args, **kwargs)return wrap_functiondecorate_Adef print_message_A(args, *kwargs):print(kwargs[str])print_message_A()第二种约定好参数直接修改参数def decorate_B(function):def wrap_function(*args, **kwargs):str Hello!return function(str, *args, **kwargs)return wrap_functiondecorate_Bdef print_message_B(str, args, *kwargs):print(str)print_message_B()第三种通过 *args 注入def decorate_C(function):def wrap_function(*args, **kwargs):str Hello!#args.insert(1, str)args args (str,)return function(*args, **kwargs)return wrap_functionclass Printer:decorate_Cdef print_message(self, str, *args, **kwargs):print(str)p Printer()p.print_message()Decorator的副作用到这里我相信你应该了解了整个Python的decorator的原理了。相信你也会发现被decorator的函数其实已经是另外一个函数了对于最前面那个hello.py的例子来说如果你查询一下foo.__name__的话你会发现其输出的是“wrapper”而不是我们期望的“foo”这会给我们的程序埋一些坑。所以Python的functool包中提供了一个叫wrap的decorator来消除这样的副作用。下面是我们新版本的hello.py。文件名hello.pyfrom functools import wrapsdef hello(fn):wraps(fn)def wrapper():print hello, %s % fn.__name__fn()print goodby, %s % fn.__name__return wrapperhellodef foo():foo help docprint i am foopassfoo()print foo.__name__ #输出 fooprint foo.__doc__ #输出 foo help doc当然即使是你用了functools的wraps也不能完全消除这样的副作用。来看下面这个示例from inspect import getmembers, getargspecfrom functools import wrapsdef wraps_decorator(f):wraps(f)def wraps_wrapper(*args, **kwargs):return f(*args, **kwargs)return wraps_wrapperclass SomeClass(object):wraps_decoratordef method(self, x, y):passobj SomeClass()for name, func in getmembers(obj, predicateinspect.ismethod):print Member Name: %s % nameprint Func Name: %s % func.func_nameprint Args: %s % getargspec(func)[0]输出Member Name: methodFunc Name: methodArgs: []你会发现即使是你你用了functools的wraps你在用getargspec时参数也不见了。要修正这一问我们还得用Python的反射来解决下面是相关的代码def get_true_argspec(method):argspec inspect.getargspec(method)args argspec[0]if args and args[0] self:return argspecif hasattr(method, __func__):method method.__func__if not hasattr(method, func_closure) or method.func_closure is None:raise Exception(No closure for method.)method method.func_closure[0].cell_contentsreturn get_true_argspec(method)当然我相信大多数人的程序都不会去getargspec。所以用functools的wraps应该够用了。一些decorator的示例好了现在我们来看一下各种decorator的例子给函数调用做缓存这个例实在是太经典了整个网上都用这个例子做decorator的经典范例因为太经典了所以我这篇文章也不能免俗。from functools import wrapsdef memo(fn):cache {}miss object()wraps(fn)def wrapper(*args):result cache.get(args, miss)if result is miss:result fn(*args)cache[args] resultreturn resultreturn wrappermemodef fib(n):if n 2:return nreturn fib(n - 1) fib(n - 2)上面这个例子中是一个斐波拉契数例的递归算法。我们知道这个递归是相当没有效率的因为会重复调用。比如我们要计算fib(5)于是其分解成fib(4) fib(3)而fib(4)分解成fib(3)fib(2)fib(3)又分解成fib(2)fib(1)…… 你可看到基本上来说fib(3), fib(2), fib(1)在整个递归过程中被调用了两次。而我们用decorator在调用函数前查询一下缓存如果没有才调用了有了就从缓存中返回值。一下子这个递归从二叉树式的递归成了线性的递归。Profiler的例子这个例子没什么高深的就是实用一些。import cProfile, pstats, StringIOdef profiler(func):def wrapper(*args, **kwargs):datafn func.__name__ .profile # Name the data fileprof cProfile.Profile()retval prof.runcall(func, *args, **kwargs)#prof.dump_stats(datafn)s StringIO.StringIO()sortby cumulativeps pstats.Stats(prof, streams).sort_stats(sortby)ps.print_stats()print s.getvalue()return retvalreturn wrapper注册回调函数下面这个示例展示了通过URL的路由来调用相关注册的函数示例class MyApp():def __init__(self):self.func_map {}def register(self, name):def func_wrapper(func):self.func_map[name] funcreturn funcreturn func_wrapperdef call_method(self, nameNone):func self.func_map.get(name, None)if func is None:raise Exception(No function registered against - str(name))return func()app MyApp()app.register(/)def main_page_func():return This is the main page.app.register(/next_page)def next_page_func():return This is the next page.print app.call_method(/)print app.call_method(/next_page)注意1)上面这个示例中用类的实例来做decorator。2)decorator类中没有__call__()但是wrapper返回了原函数。所以原函数没有发生任何变化。给函数打日志下面这个示例演示了一个logger的decorator这个decorator输出了函数名参数返回值和运行时间。from functools import wrapsdef logger(fn):wraps(fn)def wrapper(*args, **kwargs):ts time.time()result fn(*args, **kwargs)te time.time()print function {0}.format(fn.__name__)print arguments {0} {1}.format(args, kwargs)print return {0}.format(result)print time %.6f sec % (te-ts)return resultreturn wrapperloggerdef multipy(x, y):return x * yloggerdef sum_num(n):s 0for i in xrange(n1):s ireturn sprint multipy(2, 10)print sum_num(100)print sum_num(10000000)上面那个打日志还是有点粗糙让我们看一个更好一点的(带log level参数的)import inspectdef get_line_number():return inspect.currentframe().f_back.f_back.f_linenodef logger(loglevel):def log_decorator(fn):wraps(fn)def wrapper(*args, **kwargs):ts time.time()result fn(*args, **kwargs)te time.time()print function fn.__name__,print arguments {0} {1}.format(args, kwargs)print return {0}.format(result)print time %.6f sec % (te-ts)if (loglevel debug):print called_from_line : str(get_line_number())return resultreturn wrapperreturn log_decorator但是上面这个带log level参数的有两具不好的地方1) loglevel不是debug的时候还是要计算函数调用的时间。2) 不同level的要写在一起不易读。我们再接着改进import inspectdef advance_logger(loglevel):def get_line_number():return inspect.currentframe().f_back.f_back.f_linenodef _basic_log(fn, result, *args, **kwargs):print function fn.__name__,print arguments {0} {1}.format(args, kwargs)print return {0}.format(result)def info_log_decorator(fn):wraps(fn)def wrapper(*args, **kwargs):result fn(*args, **kwargs)_basic_log(fn, result, args, kwargs)return wrapperdef debug_log_decorator(fn):wraps(fn)def wrapper(*args, **kwargs):ts time.time()result fn(*args, **kwargs)te time.time()_basic_log(fn, result, args, kwargs)print time %.6f sec % (te-ts)print called_from_line : str(get_line_number())return wrapperif loglevel is debug:return debug_log_decoratorelse:return info_log_decorator你可以看到两点1)我们分了两个log level一个是info的一个是debug的然后我们在外尾根据不同的参数返回不同的decorator。2)我们把info和debug中的相同的代码抽到了一个叫_basic_log的函数里DRY原则。一个MySQL的Decorator下面这个decorator是我在工作中用到的代码我简化了一下把DB连接池的代码去掉了这样能简单点方便阅读。import umysqlfrom functools import wrapsclass Configuraion:def __init__(self, env):if env Prod:self.host coolshell.cnself.port 3306self.db coolshellself.user coolshellself.passwd fuckgfwelif env Test:self.host localhostself.port 3300self.user coolshellself.db coolshellself.passwd fuckgfwdef mysql(sql):_conf Configuraion(envProd)def on_sql_error(err):print errsys.exit(-1)def handle_sql_result(rs):if rs.rows 0:fieldnames [f[0] for f in rs.fields]return [dict(zip(fieldnames, r)) for r in rs.rows]else:return []def decorator(fn):wraps(fn)def wrapper(*args, **kwargs):mysqlconn umysql.Connection()mysqlconn.settimeout(5)mysqlconn.connect(_conf.host, _conf.port, _conf.user,_conf.passwd, _conf.db, True, utf8)try:rs mysqlconn.query(sql, {})except umysql.Error as e:on_sql_error(e)data handle_sql_result(rs)kwargs[data] dataresult fn(*args, **kwargs)mysqlconn.close()return resultreturn wrapperreturn decoratormysql(sql select * from coolshell )def get_coolshell(data):... ...... ..线程异步下面量个非常简单的异步执行的decorator注意异步处理并不简单下面只是一个示例。from threading import Threadfrom functools import wrapsdef async(func):wraps(func)def async_func(*args, **kwargs):func_hl Thread(target func, args args, kwargs kwargs)func_hl.start()return func_hlreturn async_funcif name __main__:from time import sleepasyncdef print_somedata():print starting print_somedatasleep(2)print print_somedata: 2 sec passedsleep(2)print print_somedata: 2 sec passedsleep(2)print finished print_somedatadef main():print_somedata()print back in mainprint_somedata()print back in mainmain()其它
http://www.pierceye.com/news/12474/

相关文章:

  • 唐山建设公司网站平度市网站建设
  • 怎么建自己公司网站工作地点相对湿度大于75%
  • 设计网站与建设单页网站内链接
  • 网站建设的一些销售技巧郑州模板网站
  • 常德网站seo动易网站 自定义邮箱
  • jsp网站设计教学做一体化教程软件开发流程书籍
  • 网站建设所出现的问题体育设施建设网站
  • 北京性价比网站建设建网站几个按钮
  • 网站模板的制作怎么做的哪个网站可以做围棋作业
  • 盐城建设厅网站设计备案佛山新网站制作特色
  • 环保网站怎么做网站推广公司傻大白
  • 深圳做分销网站建设网站由哪些部分组成部分组成部分组成
  • 杭州网站优化wordpress本地访问慢
  • 电子商务网站建设的方法有哪些个人网页主页
  • asp网站首页模板服务器管理软件
  • 网站搭建需要的公司织梦网站自助申请友链代码
  • 网站设计维护内容上海分公司
  • 小语言网站建设游戏制作软件免费版
  • 营销型网站建站公司网络工程师是青春饭吗
  • asp技术做网站苏州网站建设新手
  • 网站代运营做哪些无网站无产品链接如何做SOHO
  • 连云港建设网站公司江西企业登记网络服务平台
  • 潍坊网站制作建设学校网站建设注意什么
  • 单位网站建设情况总结网站建设及相关流程
  • 南京城乡建设局网站首页青海最新信息
  • 电子商务网站建设平台wordpress网站logo没显示
  • 微信公众号红包网站开发漳州企业网站建设制作
  • 网站及微站建设合同验收网站开发需求分析内容
  • 安徽 电子政务网站定制北京网站公司哪家好
  • 企业网站建立wordpress设置内容标题