返回顶部
首页 > 资讯 > 后端开发 > Python >3.关于python函数,以及作用域,递
  • 956
分享到

3.关于python函数,以及作用域,递

函数作用python 2023-01-31 07:01:46 956人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

一.使用函数编程的好处。大大的提高了代码的重用行,重复的逻辑或者操作,可以定义到一个函数里,多次调用。下面是关于提高代码重用性的例子。现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时

一.使用函数编程的好处。

大大的提高了代码的重用行,重复的逻辑或者操作,可以定义到一个函数里,多次调用。

下面是关于提高代码重用性的例子。

现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了所有的知识量,写出了以下代码。

  while True:

      if cpu利用率 > 90%:

          #发送邮件提醒

          连接邮箱服务器

          发送邮件

          关闭连接

       

      if 硬盘使用空间 > 90%:

          #发送邮件提醒

         连接邮箱服务器

         发送邮件

         关闭连接

      

     if 内存占用 > 80%:

         #发送邮件提醒

         连接邮箱服务器

         发送邮件

         关闭连接

上面这段代码可以看出,每一段代码的重复的地方特别多。

如果日后还需要增加群发功能,从上到下,所有的代码都需要去修改。


def 发送邮件(内容)

    #发送邮件提醒

    连接邮箱服务器

    发送邮件

    关闭连接

     

while True:

     

    if cpu利用率 > 90%:

        发送邮件('CPU报警')

     

    if 硬盘使用空间 > 90%:

        发送邮件('硬盘报警')

     

    if 内存占用 > 80%:

        发送邮件('内存报警')

这段代码就是使用了函数式编程写出的代码,从这段代码中可以有个很明显的特点,把重复的代码单独拿出来,定义了一个函数(也就是放到一个公共的空间,也相当于给这段代码起了个名字),如果以后需要多次使用这个代码,只要调用这个名字就可以了。





二.关于python中函数的返回值。

当定义了一个函数,如果不使用return给任何返回值,默认就会返回None。

下面就是例子。

def func01():

    print "this is func"

def func02():

    print "this is func"

    return 2

test1 = func01()

>>>this is func

test2 = func02()

>>>this is func

print test1

>>>None

print test2

>>>2

在上面定义了两个函数,分别是func01和func02,这两个函数的功能都是打印输出同一句话“this is func”,func01没有定义任何返回值,返回给test1变量的是个空值(None),func02使用return定义了一个返回值,返回的是数字2,返回给test2的就是数字2。


那么一个函数,在被调用一次的时候,是否可以同时!注意!是同时!返回多个值呢?(不同if分支判断中的return不能算同时!)

我们来试一下。


def func01():

    print "this is func"

#定义的第一个函数func01,没有定义任何返回值。


def func02():

    print "this is func"

    return 2

#定义的第二个函数func02,定义了一个返回值,返回一个整数2。


def func03():

    print "this is func"

    return 1

    return 2

#定义的第三个函数func03,使用两次return,定义了两个返回值,分别是1和2。


def func04():

    print "this is func"

    return 1,2,3,4

#第四个函数func4,使用一个return返回四个整数,这四个整数使用逗号隔开。

test1 = func01()

test2 = func02()

test3 = func03()

test4 = func04()

#将这四个函数的返回值分别赋给变量,然后看看每个函数的返回值都是什么。


print test1

>>>None

#第一个函数的返回值为空,因为之前说了,函数如果不定义任何返回值,默认就返回None空值。

print test2

>>>2

#第二个函数,返回了一个整数2,因为使用return指定了返回值,所以就返回了一个整数2,如果返回值是字典,那么return返回的也是个字典。(当返回值只有一个的时候,retrun什么数据类型,就会返回什么数据类型!!这点很重要!)

print test3

>>>1

#第三个函数,在定义的时候写了两个return,但是只返回了一个值,这个值是整数1。

#明明使用两个return,但是只返回了一个返回值?!~是的,没错,下面要强调一个关于Python函数很重要的知识点!

#当python函数在之行的时候,一旦遇到return,函数直接退出!return后面的所有代码都不会被执行!!!!!这点很重要!!!

不信我们可以试试~

现在我将func03函数做了一下修改。

def func03():

    print "this is func"

    return 1

    print "hamasaki ayumi"

    return 2

#我在两个retrun中间插了一行代码,打印字符串“hamasaki ayumi”,这个字符串放到了第一个return后面,看看会不会被执行

test3 = func03()

print test3

>>>1

#见证“奇迹”的时刻到了。

#func03函数依旧只返回了第一个rerun中定义的整数1,第一retrun执行结束后,函数直接退出了,retrun 1后面的所有代码都没有被执行!这也就验证了刚才所说的,当函数执行时,遇到retrun,返回相应的返回值之后,函数直接退出,retrun后面的所有代码都不会被执行。




print test4

>>>(1, 2, 3, 4)

#第四个函数,也只返回了一个元组,之前定义的返回值,1,2,3,4四个整数,被装进了同一个元组中,这也说明了一个问题,就是,当retrun要返回多个值的时候,会把这些同时返回的多个值,装进同一个元组中。

那么可能有人会问,如果同时返回多种数据类型呢?在同一个返回值中,有字典,有列表,有元组会是什么效果?

可以肯定的告诉你,返回的这些字典,列表,元组,字符串,统统会被打包进一个元组~

做个测试吧。

现在将func04函数做了一下修改。

修改了一下func04的返回值,现在这个返回值里面充满了各种数据类型,有字典,有数字,有字符串,有元组,有列表,看看最后会返回值是什么。

def func04():

    print "this is func"

    return 1,2,3,4,['a','b','c','d'],'hello',{'k1':'v1','k2':'v2'},(9,8,7,6,5)

test4 = func04()

print test4

>>>(1, 2, 3, 4, ['a', 'b', 'c', 'd'], 'hello', {'k2': 'v2', 'k1': 'v1'}, (9, 8, 7, 6, 5))

#可以看到这些不同数据类型的所有对象都被装进了同一个元组~


接下来对函数的返回值做个小结:

  1. 在python中,如果没有给函数定义任何返回值,默认返回值为None。

  2. python中的函数不可以同时retrun多次,当函数执行的时候,读到第一个retrun时,函数就会退出执行,retrun后面的代码都将不会被执行。

  3. 在python的函数中,只return一个对象的话,return的对象是什么类型的数据,返回的就是什么类型的数据。

  4. 在python函数中,如果要return多个对象,这些对象同时都会被装进一个元组并返回。

关于python函数的返回值在这里就说完了,接下来说说函数传参。




三.关于函数的参数。

说的函数的参数,就要先说说形参和实参的概念了,我理解的型参,就是函数用来接受实际参数的一个“位置”,这个位置只有在函数在调用的时候,才会被分配到内存中去,一旦函数调用结束,型参所在的内存单元会被释放,换句话说,这种形参只能在函数内部使用。

def func1(a,b):

    c=a+b

    return c

#上面定义了一个函数,函数名为func1,里面的a和b就是型参。


下面在说说实参,实参可以是表达式,常量,变量,函数,以及各种对象....总之要有实际的值,因为必须要有确定的值,才可以把它传递给型参。(实参,就是调用函数时,给函数传的值或参数。)

print func1(1,2) #调用上面定义的func1函数

>>>3

在调用func1函数时,传给函数内部型参的1,2就是所谓的实参。

下面来说说函数的传参方式。


  1. 按形参的顺序给函数传递参数。

def func1(name,city):

    print "name:%s city:%s" %(name,city)

#定义了一个函数,里面定义了两个形参,分别是name和city。

func1 ("hamasaki ayumi","Fukuoka")

#刚刚定义的func1函数定义了两个形参,先定义的name,再定义的city,现在按照刚刚定义的顺序给函数传参。

>>>name:hamasaki ayumi city:Fukuoka

参数被按顺序传递到了函数中。

如果传参时不按顺序呢?

func1 ("Fukuoka","hamasaki ayumi")

>>>name:Fukuoka city:hamasaki ayumi

#所传的参数顺序反过来了。


  2.手动指定形参和实参的对应关系,一个函数中定义了很多型参,这些形参的顺序很难记住,如果不想按照型参的顺序去传递参数,在调用函数的时候,可以手动指定哪个形参去接收哪个实参。(这个也叫叫关键字参数!)

def func1(name,city):

    print "name:%s city:%s" %(name,city)

func1 (city = "Fukuoka",name = "hamasaki ayumi")

>>>name:hamasaki ayumi city:Fukuoka

从这可以看出,手动指定了形参和实参的对应关系,即使不按照顺序去传参数,参数传递的位置也不会出错。(前提是形参和实参的顺序一定要对应)


3.默认参数,默认参数是函数在定义过程中,在形参中指定的,当调用函数的时候,没有给该函数的形参传递指定的实参,那么这个形参直接等于在创建函数时定义的默认参数。

(说简单一点,就是在定义函数的时候,给了某个参数一个默认参数,如果没传参数,这个参数直接等于它的默认值)

下面是关于默认参数的例子:

def func2(name,sex="male"):   #创建函数,定义了一个默认值sex默认等于male

    print "name:%s sex:%s" %(name,sex)


func2("name = ayumi")  #在调用函数的时候,只传了一个参数,在调用函数的时候没有给sex传参,sex默认就等于了male。

>>>name:ayumi sex:male


func2(name = "ayumi",sex = "female")

再次调用下func2函数,给sex也传一个参数,看看是否可以覆盖默认值。

>>>name:ayumi sex:female


三.函数参数收集。

  1. 一次性传递多个参数,将多个参数传递到一个元组中。

如果想要让一个形参可以收集多个值,但值这些值会被装进元组,当作一个参数传递给函数,想实现这种效果,只要在定义函数时,给指定的形参前面加一个*星号就可以做到。

def func1(a,*args): #定义了两个形参,分别时a和args,其中在args前面加了一个*,来看看传参的效果是怎么样的。

    print a

    print args

func1(1,2,3,4,5,6)

>>>1

        (2, 3, 4, 5, 6)


参数1给了a,2,3,4,5,6打包成了元组,传给了args。

在参数前面加上*就是可变参数。在函数内部,参数args接收得到的是一个tuple元组,调用该函数时,可以传入任意个参数,包括0个参数(如果不给可变的形参传递任何参数,它默认就会等于一个空元组)。

我们可以来测试下。

def func1(a,*args):

    print a

    print args


func1(1)#调用func1函数的时候,没有给args传递任何实参数,看看会返回什么。

>> 1

      ()

args返回了一个空的元组。

当*args遇到关键字参数的时候会出现什么样的效果呢?

func1(1,k1='aaa')

Traceback (most recent call last):

  File "/Users/Macbook/PyCharmProjects/untitled1/2day.py", line 5, in <module>

    func1(1,k1='aaa')

TypeError: func1() Got an unexpected keyWord argument 'k1'

#结果抛出了个异常~

如果想传递多个关键字参数给函数,在定义形参的时候,需要在前面加**两个星号,下面就来说说这种可以传递多个关键字参数的写法。


    2.一次性传递多组参数,每组参数被传递到一个字典中,作为字典的键值对。

让一个形参可以收集多个关键字参数,每个关键字参数都将作为键值对被装进同一个字典,当作一个参数传递给函数,想实现这种效果,只要在定义函数时,给指定的形参前面加两个**星号,就可以实现这种功能。

def func1(a,**kwargs):

    print a

    print kwargs

func1(1,k1='aaa',k2='ccc',k3='DDD')

>>>1

    {'k3': 'ddd', 'k2': 'ccc', 'k1': 'aaa'}


func1(1)

>>>1

        {}

和一个*星号一样,**星号依旧是可变的形参,两个星号的形参如果不传递任何参数,默认会返回一个空字典。


3.当*单个星号和**两个星号,还有普通的形参放在一起用,会出现什么效果?

def test_func(a,b,c,*args,**kwargs):

    print "a = %s" %(a)

    print "b = %s" %(b)

    print "c = %s" %(c)

    print "args= ",args

    print "kwargs =",kwargs

test_func(1,2,3,4,5,6,k1="v1",k2="v2")

输出结果如下:

a = 1

b = 2

c = 3

args=  (4, 5, 6)

kwargs = {'k2': 'v2', 'k1': 'v1'}



四,分解序列传参。

在给python函数传递参数时,如果需要把一个列表,或者元组中的每一个元素拆开,依旧可以适用*单个星号来实现。

不过需要注意的是!!!这次的星号不是放在定义函数的形参前面的!!而是放在实参前面的。

举个例子就可以看明白了。

def func1(*args):  #定义了一个函数,给了这个函数一个可变的形参。

    print args

接下来调用func1函数,给这个函数的可变的形参传一个列表。

func1([1,2,3,4,5,6])

>>>([1, 2, 3, 4, 5, 6],)

最后,返回了一个元组,整个列表变成了元组中的一个元素。


接下来,我们在给函数传参的时候,在序列前面加一个*星号,看看会出现什么效果。

func1(*[1,2,3,4,5,6])

>>>(1, 2, 3, 4, 5, 6) 

#从显示的结果可以看到,列表中的每一个元素,都单独作为一个元素,放在了元组里面。

而不是将一个列表当成一个元素放进元组里。


补充!*星号基本的序列都可以拆开,比如说字符串~

func1(*"hello")

>>>('h', 'e', 'l', 'l', 'o')


func1("hello")

>>>('hello',)

这是加星号和不加星号的对比。

字符串中每一个字母都被拆开,放进了元组。


五.如何把字典直接传进函数。

现在有一个字典类型的值,需要把这个字典完整的传到函数中,该怎么做?

首先,我们先来试试,在调用函数的时候,只使用一个*信号,看看能不能把字典传到列表中。


def func1(*args):

    print args

首先,试试第一种方法,在函数中定义了一个可变的形参,接受所有参数,将所有接收到的参数,都放到同一个元组中。

func1({'k1':'v1','k2':'v2'})

>>>({'k2': 'v2', 'k1': 'v1'},)

在调用func1函数的时候,传参,不做任何分解,直接把字典传给那个可变的形参*args,最后的结果就是,这个字典的确是被传到了函数内部,但是这个字典被放到了一个元组中。


然后我们在试试第二个方法。

还是上面定义的func1函数,在把字典传进去之前,在前面加个*号,看看会是什么效果。

func1(*{'k1':'v1','k2':'v2'})

>>>('k2', 'k1')

只把两个key放到了元组中,没有达到想要的结果。


第三种方法,在传参的时候使用两个**星号。

def func2(**kwargs):

    print kwargs

func2(**{'k3': 'v3', 'k2': 'v2', 'k1': 'v1'})

>>> {'k3': 'v3', 'k2': 'v2', 'k1': 'v1'}


使用两个**星号,成功的把字典原原本本的传到了函数中。

补充!如果只是按照函数赋值的角度来说的话,

func2(**{'k3': 'v3', 'k2': 'v2', 'k1': 'v1'}) 和func2(k1 = 'v1',k2 = 'v2',k3 = 'v3'),效果是一模一样的。


五.关于函数与作用域。

说到作用域,就要先来说说变量,什么是变量,变量就是一个值的名字,现在定义一个变量为x = 1,也就是将1这个整数赋值给了x,然后通过引用x这个变量名,可以获得这个整数1,这种形式和字典特别像,通过一个key,去取对应的value,这个变量名和变量值的对应所用的是个看不见的字典,如果想看这个‘字典’,可以使用var()函数来进行查看。


注意啦!!!与作用域息息相关的三个函数var()函数和locals()函数还有global() 这三个函数会放在面向对象的时候一起做补充~~在这里只是简单说一下,先挖个坑~嘿嘿。


这种我们看不到的“字典”就是作用域,除了全局的作用域外,每个函数调用都会创建一个新的作用域。

下面,来看一个现象。

#!/usr/bin/python2.7

# -*- coding:utf-8 -*-

def foo():    #首先,定义了一个函数,这个函数里面定义了一个x=130,然后在函数的外面定义了一个变量,x = 1,执行foo()函数,那么最后x等于多少?


    x = 130


x = 1

foo()

print x

>>>1

最后,x还是等于1。

原本以为执行了foo函数后,会重新定义x变量,但是函数执行结束后,x的值并没有发生改变,这就是因为在调用函数foo的时候,新的命名空间被创建了,x = 130只在这个变量的内部作用域(局部的命名空间)起作用,不会影响到函数外部(全局)作用域中的x变量,因此,函数内部的变量都被称为局部变量。

但是如果要在函数的内部访问全局变量该怎么做?

如果在函数内部,只是单纯的读取全局变量,是完全没有问题的,只要不重新赋值就没有任何问题。

(补充~使用global声明或者全局变量是列表,字典之类的可辨类型除外)

不信可以来测试一下。

def f1():

    print x

x = 1

f1()

>>> 1

从上面的测试可以看出,如果在函数内部只是访问全局变量的话,是没有任何问题的。


如果函数中有global关键字,那么被global声明的变量,直接变成全局变量。



注意啦!!!!!读取全局变量一般来说,不会出什么问题,但是啊,如果局部变量名或者参数名,和想要访问的全局变量中的变量名有冲突,那么,在这个函数中,就无法直接访问这个全局变量了,局部变量会把全局变量给临时性的“覆盖”。说的通俗点,就是当局部变量和全局变量名相同,在函数内部访问的话,以局部变量为准!!

说到了变量和作用域,又不得不提到三个函数,分别是vars(),globals(),locals(),这三个函数在本篇文章中,只做个简单的解释,等博主写到面向对象编程时,会详细说下这三个函数的具体功能。

  1. locals() 首先上官方解释:Update and return a dictionary containing the current scope's local variables. 博主英语比较渣,查了下不会的单词,大概可以翻译为,更新或者返回一个字典,这个字典中包含了当前范围的本地变量。

locals这个函数,根据博主亲测,当放到哪个作用域,就会以字典的形式返回当前作用域中的所有名称空间的所有值(所有的变量名和变量值)。

x = 1

def f1():

    a = "abc"

    print "locals = ",locals()


f1()

locals =  {'a': 'abc'}


print locals()

{'f1': <function f1 at 0x102efa668>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': '/Users/macbook/PycharmProjects/untitled1/test.py', '__package__': None, 'x': 1, '__name__': '__main__', '__doc__': None}


#分别在全局作用域和f1函数中都调用了一次locals()函数,结果已经很明显了,在f1函数内部调用locals函数后,返回了f1函数作用域中所有的变量名以及对应的变量值,接着,又在函数外,也就是全局作用域调用了一下locals()函数,结果返回了全局作用域中的所有变量名和变量值(名称空间)的使用情况。


    2.globals() Return the dictionary containing the current scope's global variables. 返回一个字典,包涵当前范围全局变量。

globals函数,用于返回全局变量中所有的变量名以及变量值( 名称空间)的使用情况。

globals函数不管放在任何作用域,显示的都是全局作用域中的变量名和变量值。


    3.vars()  这个函数原本想放在面向对象的时候在详细说说的,因为涉及到了“对象”相关的知识点。

先来看看官方怎么解释吧。

def vars(p_object=None): # real signature unknown; restored from __doc__

    """

    vars([object]) -> dictionary

    

    Without arguments, equivalent to locals().

    #没有参数时,相当于locals()函数。

#这句话就是说,当vars()函数在没传任何参数之前,和locals()函数是一模一样的。

    With an argument, equivalent to object.__dict__.

#有一个参数传进来的时候,作用就相当于一个对象的__dict__方法。

    """

    return {}


官方的意思就是说vars()这个函数如果不加参数,功能和local函数一样,如果加了参数,就可以以字典的方式,返回这个对象内部的变量,在python这门语言中,一切皆对象,变量名,函数名,都是对象,如果想看这些对象内部都包涵什么变量的话,vars(对象名)就可以看到了,给vars函数传一个对象的名称。

def f1():

    a = 1 #在这个例子中,我特别在函数中定义了一个变量a = 1,是为了防止f1对象中变量和f1函数的变量混淆

    pass

vars(f1)

>>>{'x': 1}


vars(对象名) = 对象.__dict__ 这两个作用是一模一样的。


下面补充一个关于globals()函数使用的小技巧!

当函数内部变量和全局环境下的变量名一模一样,这时两个一模一样的变量名,就会以函数内部的变量值为准,这样,函数就无法访问这个函数外部同名的全局变量了,如果想访问函数外部的全局变量,就可以借助globals() 函数去拿全局变量。

下面是例子:

在没有使用globals()函数之前,是无法访问同名全局变量的。

name = "suhaozhi"

def test1():

    name = "hamasaki"

    print name

test1()

>>>hamasaki


函数test1想要访问外部的name = “suhaozhi”这个变量,但是只能访问到函数内部的name = “hamasaki”。


接下来,我们就使用globals()函数去取全局name变量。

name = "suhaozhi"

def test1():

    name = "hamasaki"

    print globals()['name']

test1()

>>>suhaozhi

全局变量中name的值被成功取到了。



六.在python中函数不只可以向后引用,也可以向前引用。

下面是两个例子:

  1. 最常见的向后引用。

def func1():

    print 'in the func1'

def func2():

    print "in the func2"

    func1()

func2()

>>> in the func2

in the func1


    2.向前引用。

def func2():

    print "in the func2"

    func1()

def func1():

    print 'in the func1'

func2()

>>> in the func2

in the func1


七.函数嵌套。

首先,来看一个函数嵌套的例子,然后分析它的执行过程。

name = "suhaozhi"

def f1():

    name = "f1"

    def f2():

        name = "f2"

        print name

    f2()

    print name

f1()

print name


开始执行f1函数。

第一步:在f1内部加载局部变量name = “f1”.

第二步:加载f2函数。

第三步:执行f2函数,并先打印一个字符串“f2”。

第四步:f1内部的f2函数执行完毕,退出到f1函数,打印f1中的name变量,打印“f1”字符串。

第五步:f1函数执行完毕,退出函数,开始打印全局变量name = "suhaozhi"。


八. 函数递归

函数自己调用自己,就是所谓的递归。

def func1():

    print "in the func1"

    func1()

func1()

#上面这个例子,就是基于函数递归的特性完成的一个“死循环”。

func1函数做了两个动作,输出一个"in the func1"然后再次执行func1函数,然后再输出"in the func1"...

会一直循环下去。


所以说,在做函数递归的时候,必须有个明确的结束条件(使用return去终止)。

说简单点,就是在函数中使用if条件判断,然后在指定的条件下return。

下面是一个使用函数递归实现的数字递减。

def func1(n):

    print n

    if n - 1 == 0:

        return n

    return func1(n - 1)

func1(10)

#调用func1函数,给n传了一个整数10.

#现在n = 10 打印一次变量n会显示一次10

#开始if判断,10 - 1不等于0,条件不成立,则执行下面的return func1(n - 1),也就是在函数内部继续调用func1函数,并且把n - 1

#这时,n = 9 再次进入if判断 9 - 1也不等于0,条件不成立,然后继续调用func1函数 n继续 - 1 ,此时n = 8 .........以此类推.

#一直到n == 0 执行retrun n


第二点,每次更深入一层递归,问题规模要比上次递归有所减少。

关于这个问题,前两天看到了一个很不错的例子。

# -*- coding:utf-8 -*-

import time

perscon_list = ['a','b','c','d','ayumi']

def find_person(person_list):

    print '*' * 60

    person = person_list.pop(0)

    if person_list == False:

        print "We don't even know her~"

        return None

    if person == "ayumi":

        return "Everyone is a bitch jolin,right?she is a bitch jolin"

        #print "%s:Everyone is a bitch jolin,right?she is a bitch join" %(person)

    print "请问%s,你认识bitch jolin吗?" %(person)

    print "i don't know her~ But I can help you ask ",person_list

    time.sleep(3)

    re = find_person(person_list)

    print "%s问的结果是,%s" %(person,re)

    return re

print find_person(perscon_list)


上面这个例子的输出结果是:

************************************************************

请问a,你认识bitch jolin吗?

i don't know her~ But I can help you ask  ['b', 'c', 'd', 'ayumi']

************************************************************

请问b,你认识bitch jolin吗?

i don't know her~ But I can help you ask  ['c', 'd', 'ayumi']

************************************************************

请问c,你认识bitch jolin吗?

i don't know her~ But I can help you ask  ['d', 'ayumi']

************************************************************

请问d,你认识bitch jolin吗?

i don't know her~ But I can help you ask  ['ayumi']

************************************************************

d问的结果是,Everyone is a bitch jolin,right?she is a bitch jolin

c问的结果是,Everyone is a bitch jolin,right?she is a bitch jolin

b问的结果是,Everyone is a bitch jolin,right?she is a bitch jolin

a问的结果是,Everyone is a bitch jolin,right?she is a bitch jolin

Everyone is a bitch jolin,right?she is a bitch jolin


(第二个例子是真正意义上的递归,实现了返回值回传)


递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

堆栈扫盲Http://www.cnblogs.com/lln7777/arcHive/2012/03/14/2396164.html 

尾递归优化:http://egon09.blog.51cto.com/9161406/1842475


关于函数递归的最后补充:

函数自己调用自己,就是所谓的递归,当函数调用自身时,当前函数,和在函数内部调用的“自己”实机上已经是两个不同的函数了,(也就是同一个函数使用了两个不同的命名空间)。


--结束END--

本文标题: 3.关于python函数,以及作用域,递

本文链接: https://lsjlt.com/news/191841.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 3.关于python函数,以及作用域,递
    一.使用函数编程的好处。大大的提高了代码的重用行,重复的逻辑或者操作,可以定义到一个函数里,多次调用。下面是关于提高代码重用性的例子。现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时...
    99+
    2023-01-31
    函数 作用 python
  • Python函数参数传递以及变量作用域详解
    这篇文章主要介绍“Python函数参数传递以及变量作用域详解”,在日常操作中,相信很多人在Python函数参数传递以及变量作用域详解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python函数参数传递以及变...
    99+
    2023-06-04
  • 关于Python函数对象的名称空间和作用域
    目录1.函数对象(1)函数对象的引用(2)函数可以放到序列里面(3)函数可以作为参数 , 传递给另一个函数(4)函数可以作为另一个函数的返回值2.名称空间3.作用域(1)作用域的理解...
    99+
    2023-05-17
    Python 函数 Python 函数作用域 Python 函数名称空间
  • Python中关于函数的具体用法范例以及介绍
    目录1.函数的介绍2.函数的定义和调用3.函数的参数4.参数的分类4.1.位置参数4.2.关键字参数4.3.缺省参数4.4.不定长参数1.不定长参数*args2.不定长参数* * k...
    99+
    2024-04-02
  • Python函数的作用域及内置函数详解
    目录1.函数的作用域2.函数的调用详解3.内置函数总结1.函数的作用域 -- 内置 -- 全局,顶格写 -- 局部,函数内部 a = 34 #全局变量 def run(): ...
    99+
    2024-04-02
  • 关于VUE的编译作用域及slot作用域插槽问题
    什么是插槽?插槽的指令为v-slot,它目前取代了slot和slot-scope,插槽内容,vue实例一套内容分发的api,将slot元素作为承载分发内容的出口。 插槽分为单个插槽,...
    99+
    2024-04-02
  • python函数作用域简介
    1.定义:函数中变量取值的地方;2.函数中的变量名除了特殊声明为全局变量或本地变量,否则均为局部变量;3.变量的作用域解析原则:LEGB原则,即:变量名引进分为三个作用域进行查找,首先是本地,再是函数内(如果存在),之后才是全局变量,最后...
    99+
    2023-01-31
    函数 作用 简介
  • 关于scipy.optimize函数使用及说明
    目录scipy.optimize函数使用scipy.optimize模块包含什么?使用步骤使用scipy.optimize进行优化总结scipy.optimize函数使用 简单使用s...
    99+
    2022-12-14
    scipy.optimize scipy.optimize函数 scipy.optimize函数使用
  • 浅谈Python中的函数(def)及参数传递操作
    如下所示: #抽象 (函数) # 1、callable 判断一个对象是否可以被调用 x = 1 def y(): return None callable(y) # y可以被调用 callable...
    99+
    2022-06-02
    Python def函数 参数传递
  • 关于Eureka的概念作用以及用法详解
    目录一、概念1.1、什么是服务治理1.2、 什么是Eureka1.3、 Eureka包含两个组件1.4、 什么场景使用Eureka1.5、 Eureka停更1.6、代码要实现的内容二...
    99+
    2023-05-20
    Eureka概念 Eureka作用 Eureka用法
  • JavaScript函数执行、作用域链以及内存管理详解
    目录前言函数执行全局执行上下文函数执行上下文作用域链内存管理引用计数标记清除前言 在我们平常编写JavaScript代码的时候,难免会用到函数,函数里面会有各种变量,这些变量的作用的...
    99+
    2023-01-08
    JS函数执行 js作用域链 js内存管理
  • Python递归函数的原理及应用
    本篇内容主要讲解“Python递归函数的原理及应用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python递归函数的原理及应用”吧!一、什么是递归函数在函数内部,可以调用其他函数。如果一个函数...
    99+
    2023-06-15
  • Python函数命名空间,作用域LEGB及Global详析
    目录一、命名空间和作用域1.1 定义1.2 内建命名空间和内建作用域1.3 全局命名空间和全局作用域1.3 局部命名空间和局部作用域1.4 总结1.5 扩展LEGB二、Global关...
    99+
    2024-04-02
  • 基于Python函数的作用域规则和闭包(详解)
    作用域规则 命名空间是从名称到对象的映射,Python中主要是通过字典实现的,主要有以下几个命名空间: 内置命名空间,包含一些内置函数和内置异常的名称,在Python解释器启动时创建,一直保存到解释器退出。...
    99+
    2022-06-04
    详解 函数 规则
  • Python中的命名空间、作用域以及lo
          最近一直看一本python经典教材——《Python学习手册》,因为之前都是突击学的,也没有仔细看一些经典教材,所以感觉自己的基础掌握的还不是很好,虽然网络上资源多,但我觉得还是有必要买本教材来认真的读一读,底层基础决定上层建筑...
    99+
    2023-01-31
    作用 空间 Python
  • 关于python中map函数的使用
    1. 概念 map函数也是python中的一个内置函数,用法同之前讲过的filter函数类似。map在这里的意思是映射的意思,会根据提供的函数对指定序列做映射。 map函数会返回一个...
    99+
    2023-05-16
    python map python map函数
  • 浅谈python函数之作用域(python3.5)
    1 基本概念 1.1 命名空间 (namespace) 命名空间是变量名到对象的映射(name -> obj)。目前大多数的命名空间以类似于python字典的形式实现,实现形式在未来可能发生变化。命名...
    99+
    2022-06-05
    浅谈 函数 作用
  • Python中关于字典的常规操作范例以及介绍
    目录1.字典的介绍2.访问字典的值(一)根据键访问值(二)通过get()方法访问值3.修改字典的值4.添加字典的元素(键值对)5.删除字典的元素6.字典常见操作1.len 测量字典中...
    99+
    2024-04-02
  • Python中关于列表的常规操作范例以及介绍
    目录1.列表的介绍 2.打印出列表的数据1.我们可以根据下标取值进行打印2.使用for循环遍历3.使用while循环遍历3.列表的添加操作1.append()方法2.extend()...
    99+
    2024-04-02
  • 关于Python函数参数的进阶用法
    目录1、关键字参数和位置参数(1)关键字参数(2)位置参数2、接受任意数量的参数(1)接受任意数量的位置参数 (2)接受任意数量的关键字参数(3)同时接受任意数量的位置参数和关键字参...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作