目录

  • 递归算法解析
  • 冒泡排序解析
  • 装饰器解析

一. 递归

  1. 递归的定义   

    递归(Recursion),又成为递回,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。递归一词还较长用于描述以自相似方法重复事物的过程。

斐波那契数列是典型的递归案例:
F0 = 0(初始值)
F1 = 1(初始值)
对所有大于1的整数n: F(n) = F(n - 1) + F(n - 2)(递归定义)
尽管有许多数学函数均可以递归表示,但在实际应用中,递归的开销过大,因此在不是必要的情况下最好不要用到递归。

  2. 递归的原理

    (1). 例题:

def recursion(defth, a1, a2):
if defth == 5:
return a1
a3 = a1 + a2
defth = defth + 1
print(a1)
a1 = recursion(defth, a2, a3)
return a1
ret = recursion(1, 0, 1)
print(ret)

  以下这幅图为整个函数的执行过程,红色的代表一层一层的往里面嵌套,绿色的代表函数的返回值一层一层的外面返还。其实递归就是这个原理,通过一个函数的执行流在再次进入此函数,当通过一个条件返回一个值之后,一层一层的按照刚刚的执行流再次返回回去,最后得到返回值,但是递归的时候要注意两点:

  1. 他的条件,必须要使他的递归在某个条件内可以返回一个值,否则就会一直递归,直到电脑资源耗尽(Python默认有递归的次数限制)

  2. 返回值,在里面的递归函数一般要给予他一定的返回值,否则在最后一次返还递归的时候会得不到想要的值。

  

二. 冒泡排序

  1. 冒泡排序原理

    冒泡排序就是一种简单的排序算法。他重复的走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。

冒泡排序算法的运作如下:
  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

    交换数据的原理

    借助一个外围的变量先保存原来的值,然后再去通过指向地址的转换来进行交换数据。注意:当temp指向了a, 然后a再指向b的时候,temp本身的指向是没有发生改变的,就如下图,a指向了b,但是temp依然指向的是a的地址,所以他还是66

a = 66
b = 88
temp = a
a = b
b = temp

  

    冒泡排序的原理

  

 2. 冒泡排序事例

 # -*- coding:utf-8 -*-
# zhou
# 2017/6/17
list = [0, 88, 99, 33, 22, 11, 1]
for j in range(1, len(list)):
for i in range(len(list) - j):
# 如果第一个数据大, 则交换数据, 否则, 不做改变
if list[i] > list[i + 1]:
temp = list[i]
list[i] = list[i + 1]
list[i + 1] = temp
print(list)

三. 装饰器

  1. 装饰器定义

     装饰器是什么呢?简单来说就是在不改变源函数代码的基础上,对代码的一种微妙的扩展,以使得其功能进一步增强的函数。装饰器就是一个函数,一个加载在其他函数之上的函数,

    以下我们先来了解几个概念:

    <1>.  函数执行流

      由以上面的可知,函数的执行流应该是从上到下的,也就是说,代码先把第一个test1加载到内存中,然后从新开辟一块内存来存放第二个test1。

      这里应该是第一个test1的指向改到了890673481792这里。

def test1():
print('日本人.')
print(id(test1))
def test1():
print('中国人.')
print(id(test1))
test1() 执行结果:
890673481656
890673481792
中国人.

    <2>.  函数作为变量

      由以下结果可以看出来,函数名其实就是一个变量,可以用来传递的变量。

      注意:函数作为变量的时候不能加括号,必须只是函数名

def test1():
print('我是.')
a = test1
print(a)
print(test1)

结果:
<function test1 at 0x000000E2D403C7B8>
<function test1 at 0x000000E2D403C7B8>

    <3>.  函数嵌套

      这里定义了三个函数,test1,test2,test3, 3里面嵌套了1, 1里面又嵌套了2,从他的结果中想必你也会看出来函数的执行流。

def test1():
print('我是',end='')
def test2():
print('中国人.')
test2() def test3():
test1()
print('Hello, China.')
test3() 结果:
我是中国人.
Hello, China.

  2. 装饰器原理

    (1). 装饰器的写法和使用

      <1>. 装饰器也是一个函数

      <2>. 使用装饰器的格式: 在一个函数前面加上:@装饰器的名字

    (2). 装饰器的原理

      <1>. 把test1函数当做一个变量传入outer中

          func = test1

      <2>. 把装饰器嵌套的一个函数inner赋值给test1

          test1 = inner

      <3>. 当执行test1函数的时候,就等于执行了inner函数,因此在最后的那个test1()命令其实执行的就是inner,因此先输出(你是哪国人)

      <4>. 按照执行流执行到func函数的时候,其实执行的就是原来的test1函数,因此接着输出(我是中国人),并把它的返回值返回给了ret

      <5>. 当原来的test1函数执行完了之后,继续执行inner里面的命令,因此输出了(Oh,hh, I love China.)

    (3). 装饰器的总结

      由上面的执行流可以看出来,其实装饰器把之前的函数当做参数传递进去,然后创建了另一个函数用来在原来的函数之前或者之后加上所需要的功能。

# -*- coding:utf-8 -*-
# zhou
# 2017/6/17
# 定义了一个装饰器outer
def outer(func):
def inner():
print('你是哪国人?')
ret = func()
print('Oh, hh, I love China.')
return inner
@outer
def test1():
print('我是中国人.')
test1()

  3. 带参数的装饰器

    为了装饰器的高可用,一般都会采用下面的方式,也就是无论所用的函数是多少个参数,这个装饰器都可以使用

    Python内部会自动的分配他的参数。

# -*- coding:utf-8 -*-
# zhou
# 2017/6/17
def outer(func):
def inner(a, *args, **kwargs):
print('你是哪国人?')
ret = func(a, *args, **kwargs)
print('Oh, hh, I love China.')
return inner @outer
def test1(a, *args, **kwargs):
print('我是中国人.') test1(1)

  3.  装饰器的嵌套

   <1>. 第一层装饰器的简化(outer装饰器)

    

    

    <2>. 第二层装饰器简化(outer0装饰器)

    

    <3>. 装饰器嵌套攻击额,我们可以发现一层装饰器其实就是把原函数嵌套进另一个函数中间,因此我们只需要一层一层的剥开嵌套就可以了。

# -*- coding:utf-8 -*-
# zhou
# 2017/6/17
def outer0(func):
def inner():
print('Hello, Kitty.')
ret = func()
print('我是日本人.')
return inner def outer(func):
def inner():
print('你是哪国人?')
ret = func()
print('你呢?')
return inner
@outer0
@outer
def test1():
print('我是中国人.') test1() 结果Hello, Kitty.
你是哪国人?
我是中国人.
你呢?
我是日本人.

  

python系列4之装饰器的更多相关文章

  1. python设计模式之内置装饰器使用(四)

    前言 python内部有许多内建装饰器,它们都有特别的功能,下面对其归纳一下. 系列文章 python设计模式之单例模式(一) python设计模式之常用创建模式总结(二) python设计模式之装饰 ...

  2. 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解

    第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一.    引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...

  3. Python中利用函数装饰器实现备忘功能

    Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下   " ...

  4. python函数与方法装饰器

    之前用python简单写了一下斐波那契数列的递归实现(如下),发现运行速度很慢. def fib_direct(n): assert n > 0, 'invalid n' if n < 3 ...

  5. guxh的python笔记三:装饰器

    1,函数作用域 这种情况可以顺利执行: total = 0 def run(): print(total) 这种情况会报错: total = 0 def run(): print(total) tot ...

  6. python 3.x 的装饰器笔记

    今天学到了python的装饰器,感觉这个东西还是稍微有些复杂,所以记录下来,方便以后的查找.虽然标题是python 3.x的装饰器,但是我也没有怎么用过python 2.x,感觉上应该是和python ...

  7. python 中多个装饰器的执行顺序

    python 中多个装饰器的执行顺序: def wrapper1(f1): print('in wrapper1') def inner1(*args,**kwargs): print('in inn ...

  8. Python函数编程——闭包和装饰器

    Python函数编程--闭包和装饰器 一.闭包 关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数).而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数.当其中一个 ...

  9. python基础-内置装饰器classmethod和staticmethod

    面向对象编程之classmethod和staticmethod classmethod 和 staticmethod都是python内置的装饰器 classmethod 的作用:给在类内部定义的方法装 ...

随机推荐

  1. java并发编程 volatile关键字 精准理解

    1.volatile的作用 一个线程共享变量(类的成员变量.类的静态成员变量等)被volatile修饰之后,就具有以下作用: 1)并发中的变量可见性(不同线程对该变量进行操作时的可见性),即一个线程修 ...

  2. 服务器断电后 redis重启后启动不起来

    服务器断电后 redis 重启后启动不起来 原因:db持久化失败 1. 先查询redis的进程 ps -ef|grep redis 2. 查询redis的缓存文件在哪 whereis dump.rdb ...

  3. Java方法命名之“由简入繁”原则

    1.访问控制层(Controller 层)中的方法命名方向是简洁明了,向着自然化语言方向靠拢,比如“更新用户”,建议命名为“updateUser”,而非“updateUserById”,实际上我们更新 ...

  4. vue监听input标签的value值方法

    <input id="materialSearch" type="text" @keyup.enter="search" @input ...

  5. spring笔记3-AOP

    一.概述 AOP:(Aspect Oriented Programming)即:面向切面编程.把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法 ...

  6. MyEclipse内存溢出问题

    今天碰到的问题,先记录下来 Console报错: Java.lang.OutOfMemoryError: PermGen space 跟着步骤: 在这里加入:-Xms800m -Xmx800m -XX ...

  7. Spring Boot入门程序-STS

    使用Eclipse EE 中的 Spring Tool插件,完成 第一个Spring Boot应用程序的创建. 一.安装Spirng Tool插件 在 Eclipse EE Oxygen版本,安装“S ...

  8. 你真的会用ABAP, Java和JavaScript里的constructor么?

    如果constructor里调用了一个成员方法,这个方法被子类override了,当初始化一个子类实例时,父类的构造函数被的调用,此时父类构造函数的上下文里调用的成员方法,是父类的实现还是子类的实现? ...

  9. 【[TJOI2017]DNA】

    [题目][https://www.lydsy.com/JudgeOnline/problem.php?id=4892] 好像用\(SAM\)做的都是\(dfs\)啊 其实这里也是搜索 如果用\(SAM ...

  10. 在vue中同时使用过渡和动画

    在上次的动画中,在显示和隐藏有动画效果,但是,刷新页面的时候,第一次的显示没有动画效果 需求:刷新页面的时候也有动画效果 <transition name='fade' appear enter ...