false

7.8 磅
0
2

false
false
false

EN-US
ZH-CN
X-NONE


/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}
table.MsoTableGrid
{mso-style-name:网格型;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-priority:39;
mso-style-unhide:no;
border:solid windowtext 1.0pt;
mso-border-alt:solid windowtext .5pt;
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-border-insideh:.5pt solid windowtext;
mso-border-insidev:.5pt solid windowtext;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}

函数装饰器:

<![if !supportLists]>一.   <![endif]>什么是装饰器:

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

<![if !supportLists]>二.   <![endif]>为什么要用装饰器:

软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的,具体可以参考:

百度百科: https://baike.baidu.com/item/开放封闭原则/6028662?fr=aladdin

维基百科: https://zh.wikipedia.org/wiki/开闭原则

<![if !supportLists]>三.   <![endif]>要知道的三个概念:

<![if !supportLists]>1.       <![endif]>函数的作用域

<![if !supportLists]>a.       <![endif]>什么叫作用域:

在电脑程序设计中,作用域(scope,或译作有效范围)是名字(name)与实体(entity)的绑定(binding)保持有效的那部分计算机程序。不同的编程语言可能有不同的作用域和名字解析。而同一语言内也可能存在多种作用域,随实体的类型变化而不同。作用域类别影响变量的绑定方式,根据语言使用静态作用域还是动态作用域变量的取值可能会有不同的结果。

出自维基百科: https://zh.wikipedia.org/wiki/作用域

<![if !supportLists]>b.       <![endif]>Python中怎么产生不同的作用域

在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的.

来自: http://www.cnblogs.com/yuanchenqi/articles/5828233.html

<![if !supportLists]>c.       <![endif]>在Python中有几种作用域:

即:L-R-G-B

local: 局部作用域,即函数中定义的变量

enclosing: 嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的

global:全局变量,就是模块级别定义的变量

builtins: 内置作用域(python内置)

LEGB含义解释:

L-Local(function);函数内的名字空间

E-Enclosing function locals;外部嵌套函数的名字空间(例如closure)

G-Global(module);函数定义所在模块(文件)的名字空间

B-Builtin(Python);Python内置模块的名字空间

LEGB规定了查找一个名称的顺序为:local-->enclosing function locals-->global-->builtin

作者:_Zhao_

链接:http://www.jianshu.com/p/3b72ba5a209c

來源:简书

下面内容来自Python的官方文档:

4.2.2. Resolution of names

A scope defines the visibility of a name within a block. If a local variable is defined in a block, its scope includes that block. If the definition occurs in a function block, the scope extends to any blocks contained within the defining one, unless a contained block introduces a different binding for the name.

When a name is used in a code block, it is resolved using the nearest enclosing scope. The set of all such scopes visible to a code block is called the block’s environment.

When a name is not found at all, a NameError exception is raised. If the current scope is a function scope, and the name refers to a local variable that has not yet been bound to a value at the point where the name is used, an UnboundLocalError exception is raised. UnboundLocalError is a subclass of NameError.

If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block. This can lead to errors when a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations.

If the global statement occurs within a block, all uses of the name specified in the statement refer to the binding of that name in the top-level namespace. Names are resolved in the top-level namespace by searching the global namespace, i.e. the namespace of the module containing the code block, and the builtins namespace, the namespace of the module builtins. The global namespace is searched first. If the name is not found there, the builtins namespace is searched. The global statement must precede all uses of the name.

The global statement has the same scope as a name binding operation in the same block. If the nearest enclosing scope for a free variable contains a global statement, the free variable is treated as a global.

The nonlocal statement causes corresponding names to refer to previously bound variables in the nearest enclosing function scope. SyntaxError is raised at compile time if the given name does not exist in any enclosing function scope.

The namespace for a module is automatically created the first time a module is imported. The main module for a script is always called __main__.

Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace. The namespace of the class definition becomes the attribute dictionary of the class. The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes comprehensions and generator expressions since they are implemented using a function scope. This means that the following will fail:

class A:

a = 42

b = list(a + i for i in range(10))

<![if !supportLists]>2.       <![endif]>一切皆对象,即一个函数可以作为一个参数传入到另外一个函数中

<![if !supportLists]>3.       <![endif]>闭包:

<![if !supportLists]>a.       <![endif]>闭包的定义:

在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

出自维基百科: https://zh.wikipedia.org/wiki/闭包_(计算机科学)

<![if !supportLists]>b.       <![endif]>简单的理解方式:

闭包=函数块+定义函数时的环境

<![if !supportLists]>c.       <![endif]>举个栗子:

In [15]: def outer():

...:     name ="Tom"

...:     def inner():

...:         return name

...:     return inner

...:

In [16]: ret  = outer()

In [17]: ret

Out[17]: <function __main__.outer.<locals>.inner>

In [18]: ret()

Out[18]: 'Tom'

<![if !vml]>

[endif]>

如图:out()内部空间的name在外部被使用了.嗯,这就是个闭包:

还有疑问可以移步到: http://www.cnblogs.com/yuanchenqi/articles/5830025.html

<![if !supportLists]>四.   <![endif]>函数装饰器

一开始介绍了什么是装饰器,以及为什么要用装饰器,那么怎么去实现一个装饰器,以及装饰器是怎么工作的:

例如.现在有一个函数,现在需要在这个函数上新加一些功能:

<![if !supportMisalignedColumns]><![endif]>

import time

def foo():

print("hello world")

time.sleep(2)

# 现在要输出foo()实际的执行时间可以这样

def show_time():

start=time.time()

foo()

end=time.time()

print(end-start)

# 执行变成了 show_time()

# show_time()

def show_time1(f):

"""将函数作为参数传入"""

start = time.time()

f()

end = time.time()

print(end - start)

show_time1(foo)

def show_time(f):

def inner():

start = time.time()

f()

end=time.time()

print(end-start)

return inner

foo = show_time(foo)

foo()

<![if !vml]>

<![endif]>

# python提供了一种方法

@show_time    #相当于执行了foo = show_time(foo)

def foo():

print("hello world")

time.sleep(2)

foo()

<![if !vml]>

<![endif]>

执行foo()实际上相当于执行的是inner()

这时inner()就是一个闭包

当foo存在参数的时候如何处理:注意看上图,图中foo实际上即使inner

def show_time(f):

def inner(*args,**kwargs):

start = time.time()

f(*args,**kwargs)

end=time.time()

print(end-start)

return inner

@show_time

def foo(a,b):

"""foo有参数的情况"""

print(a*b)

time.sleep(2)

foo("hello",5)

<![if !vml]>

<![endif]>

突然有个想法,装饰器上还可不可以再加装饰器:

答案是可以滴:

import time

def show_time(f):

def inner(*args,**kwargs):

start = time.time()

f(*args,**kwargs)

end=time.time()

print(end-start)

return inner

def test(f):

def inner():

print("test")

f()

return inner

@test

@show_time    #相当于执行了foo = show_time(foo)

def foo():

"""foo有参数的情况"""

print("foo")

time.sleep(2)

foo()

Now 给装饰器加一个参数.

import time

def outer(flag):

def show_time(f):

def inner(*args,**kwargs):

start = time.time()

f(*args,**kwargs)

end=time.time()

print(end - start)

if flag:

print("flag为真")

else:

print("flag为假")

return inner

return show_time

@outer(" ")

def foo():

"""foo有参数的情况"""

print("foo")

time.sleep(2)

foo()

<![if !vml]>

<![endif]>

     

<![if !supportLists]>五.   <![endif]>

关于Python的装饰器的更多相关文章

  1. Python各式装饰器

    Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...

  2. Python札记 -- 装饰器补充

    本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...

  3. python基础——装饰器

    python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...

  4. 【转】详解Python的装饰器

    原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...

  5. 两个实用的Python的装饰器

    两个实用的Python的装饰器 超时函数 这个函数的作用在于可以给任意可能会hang住的函数添加超时功能,这个功能在编写外部API调用 .网络爬虫.数据库查询的时候特别有用 timeout装饰器的代码 ...

  6. python 基础——装饰器

    python 的装饰器,其实用到了以下几个语言特点: 1. 一切皆对象 2. 函数可以嵌套定义 3. 闭包,可以延长变量作用域 4. *args 和 **kwargs 可变参数 第1点,一切皆对象,包 ...

  7. 理解Python中的装饰器//这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档

    转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档 ...

  8. python基础—装饰器

    python基础-装饰器 定义:一个函数,可以接受一个函数作为参数,对该函数进行一些包装,不改变函数的本身. def foo(): return 123 a=foo(); b=foo; print(a ...

  9. 详解Python的装饰器

    Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...

  10. 关于python的装饰器(初解)

    在python中,装饰器(decorator)是一个主要的函数,在工作中,有了装饰器简直如虎添翼,许多公司面试题也会考装饰器,而装饰器的意思又很难让人理解. python中,装饰器是一个帮函数动态增加 ...

随机推荐

  1. jmeter+ant+jenkins持续集成

    邮件.报告插件和jenkins的war包下载地址:链接:https://pan.baidu.com/s/1gZJ53x50bxVyEsQFjdCkog 密码:1jtz 1.下载ant  网盘地址:链接 ...

  2. 2017CCPC秦皇岛

    热身赛 B题 Smartphone: 大整数相乘 Time Limit: 1 Second Memory Limit: 65536 KBHelianthuswolf Co. Ltd. is a mul ...

  3. IOS - 总结(网络状态变更)

    - (void)initNetworkMonitor { NSURL *baseURL = [NSURL URLWithString:@"http://www.baidu.com/" ...

  4. Python-基础-day5

    1.内置函数 2.文件操作 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 文件句柄 = file('文件路径', '模式') 注:python中打开文件有两种方式,即:open ...

  5. poj 3311 Hie with the Pie (状压dp) (Tsp问题)

    这道题就是Tsp问题,稍微加了些改变 注意以下问题 (1)每个点可以经过多次,这里就可以用弗洛伊德初始化最短距离 (2)在循环中集合可以用S表示更清晰一些 (3)第一维为状态,第二维为在哪个点,不要写 ...

  6. 【codeforces 768F】Barrels and boxes

    [题目链接]:http://codeforces.com/problemset/problem/768/F [题意] 让你把f个food和w个wine装在若干个栈里面; 每个栈只能装food或者是wi ...

  7. ASP.NET-表单验证-DataAnnotations

    DataAnnotations  [数据注解,数据注释] 需要引入两个脚本文件 <script src="@Url.Content("~/Scripts/jquery.val ...

  8. WinServer-授权规则

    授权规则: 使用谓词可以限制网站只能使用某一种请求 来自为知笔记(Wiz)

  9. 洛谷——P3398 仓鼠找sugar

    https://www.luogu.org/problem/show?pid=3398#sub 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴 ...

  10. 【SPOJ-GSHOP】Rama and Friends【贪心】【细节】

    题意: 给出n个非严格递增的整数(可能有负数),必须操作k次.每次能够把当中一个数变为它的相反数,使得终于的数列和最大. 输出这个最大和. 考验怎样出坑数据卡自己的程序... #include < ...