Python入门基础第十四课--抽象(二)

    1.前言

    接着上一节的内容,我们在这节继续说关于抽象的内容。这节涉及的内容是关于函数的一些内容:主要是参数的作用域、递归。然后会介绍一些我们在C语言里面经常见得一些算法。内容不是很多,但是很重要,要认真。

    2.作用域

    到目前为止,我们已经学了不少的知识,到底什么是变量?举个例子:x=1,当我们在解释器里面写入这样的代码的时候,名称x引用到值1。这就像字典一样,键引用值。但是在这里,x=1这样的键-值引用对我们来说是一种“不可见”的字典。而这类“不可见”的字典我们就称之为命名空间或者作用域。那么到底有多少个命名空间?一般地,除了全局作用域以外,每个函数调用都会创建一个新的作用域。我们来看看一些例子:

>>> def test(): x=100
... 
>>> x=0
>>> test()
>>> x
0

    我们写了一个test函数,在函数体外我们先给x变量绑定一个值,然后调用test函数对x变量重新绑定。但是,在最后的打印结果显示,x的值并没有发生变化这是因为当调用test函数的时候,新的命名空间就被创建了,这个命名空间只作用于函数体内的代码块,也就是说它只在局部命名空间起作用,从而它并不影响全局作用域的x。参数的工作原理类似于局部变量,所以用全局变量的名字作为参数名并没有什么问题。

    到目前为止,暂时还没有出现什么问题。有时候你想在函数体内访问全局变量也没有问题,你只想读取它而不是去重新绑定它,这是可行的。但是如果你想去重新绑定全局变量?应该怎么办?

    如果你在函数体内创建一个变量,它会自动成为一个局部变量,除非是你在函数体内声明这是一个全局变量。使用global关键字来进行声明。

#coding:utf-8
#author:youzi

x=1
def change_global():
    global x
    x+=1


change_global()
print x
/usr/local/bin/python2.7 /Users/yangjiayuan/PycharmProjects/day/day11/change_of_global.py
2

Process finished with exit code 0
    看看上面这个例子,在声明了global全局变量以后我们看到x的值被改变了,要是不是必须得,这样的操作一般不要执行,许多问题都是由此产生的。慎重使用全局变量!

    3.递归

    递归这个工具终于要登场了,简答地来讲递归就是函数自己调用自己,自己调用自己本身。一个类似的递归定义如下:

>>> def recursion(): return recursion()

    显然我们可以看到,这个函数做不了任何事情。但是从理论上讲,这个函数应该永远执行下去,每运行一次就会消耗内存,最后会以失败告终并会抛出错误:maximum recursion depth exceeded,超过最大递归深度。

    这类递归我们称为无穷递归,类似于循环的条件一直为真的情况。我们要的是一些正常而且有用的递归方式,通常有用的递归函数有下面几个部分:

  • 当函数直接返回值时候有基本实例。
  • 递归实例,包括一个或者多个问题较小部分的递归调用。

    这里问题的关键就是将问题分解为小部分,递归不可能永远执行下去,因为它总是以最小可能性问题结束,而这些问题又存储在基本实例中。每次函数被调用的时候,针对这个调用的新命名空间就会被创建,意味着当函数调用“自身”时,实际上运行的是两个不同的函数,或者是说同一个函数具有两个不同的命名空间。

    下面来看两个实例:阶乘和二分法

  • 阶乘
def factorial(n):
    result=n
    for i in range(1,n):
        result*=i
    print result
factorial(10)
def factorial(n):
    if n==1:
        return 1
    else:
        return n*factorial(n-1)


print factorial(10)
  • 二分法
def search(sequence,number,lower,upper):
    if lower==upper:
        assert number==sequence[upper]
        return upper
    else:
        middle=(lower+upper)//2
        if number >sequence[middle]:
            return search(sequence,number,middle+1,upper)
        else:
            return search(sequence,number,lower,middle)
    好了,抽象这部分内容就先到这里了,下一节我会介绍更加抽象的内容--面向对象编程。敬请期待!



猜你喜欢

转载自blog.csdn.net/qq_34454366/article/details/80262724
今日推荐