热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python3函数嵌套与递归

函数的变量:函数的变量可以分为局部变量,全局变量局部变量只能在某个函数中使用全局变量可以在整个程序中使用如何定义局部和全局变量?定义变量的时候开头没有缩进就是全局变量局部变量是在函数块里面定义的

函数的变量:
函数的变量可以分为局部变量,全局变量
局部变量只能在某个函数中使用
全局变量可以在整个程序中使用

如何定义局部和全局变量?
定义变量的时候开头没有缩进就是全局变量
局部变量是在函数块里面定义的

函数块在调用变量的时候,如果全局变量和局部变量相同,优先调用局部变量

name="chenchaozhen"
def pr():
    name="children"
    print("my name is ",name)
pr()

 

运行结果;
my name is children

如何在函数块里面定义全局变量?

name="chenchaozhen"
def pr():
    global name
    name="children"
    print("my name is ",name)
pr()
print(name)

运行结果:
my name is children
children

  ##第一个全局name变量被第二个全局name变量覆盖了,代码执行到的时候才会更改

name="chenchaozhen"
def pr1():
    print("my name is ",name)
def pr2():
    global name  #声明name是全局变量
    name="chen da zhen" #更改name,更改的是全局变量 而不是局部变量
    print("my name is ",name)

pr2()
pr1()

运行结果:
my name is chen da zhen
my name is chen da zhen

pr1()
pr2()
运行结果:
my name is chenchaozhen
my name is chen da zhen

所以执行到代码的时候 global 才会生效
如果函数内容无global 关键字,优先读取局部变量再读取全局变量,无法重新赋值给全局变量,但是当全局变量是可变类型(列表,字典)的时候,可以追加
如果函数中有global 关键字,表示函数内的局部变量本质上就是全局变量,可以读取赋值

当全局变量是可变类型(列表,字典)的时候,可以追加

name=["chen","chao"]
def pr1():
    name.append("zhen")
    print(name)
    del name[0]
    print(name)
    name.insert(1,"chen chao zhen")
    print(name)
pr1()


运行结果:
['chen', 'chao', 'zhen']
['chao', 'zhen']
['chao', 'chen chao zhen', 'zhen']
所以确定全局变量如果是可变类型的话,可以追加或者删除

但是要注意,赋值变量和声明变量不能相反,不然会报错

name=["chen","chao"]
def pr1():
    name="aa"
    global name
    print(name)
pr1()

运行结果:
"E:\Python Project\venv\Scripts\python.exe" "E:/Python Project/day3/s4.py"
File "E:/Python Project/day3/s4.py", line 4
global name
^
SyntaxError: name 'name' is assigned to before global declaration

函数里面也可以嵌套函数,先从外层运行,遇到函数,编译不执行,然后调用的时候再执行

执行顺序:从外到内 从上到下

def chen():
    2name="chen"
    2print(name)
    def chao():
        3name="chao"
        3print(name)
        def zhen():
            4name="zhen"
            4print(name)
        3print(name)
        3zhen()
    2chao()
1chen()

运行结果:

chen
chao
chao
zhen

 

name="chen"
def  test():
    name="abb"
    def testtest():
        global name
        name="xbb"
    testtest()
    print(name)
print(name)
test()
print(name)

#先执行print(name)
#再执行test()
#最后执行print(name)
运行结果:
chen
abb
xbb

 

notlocal 指的是函数的上级变量,不像global 直接指的是最上级的全局变量

前向引用:

def foo():
    print("this foo")
    bar()
def bar():
    print("this bar")

foo()

运行结果:
this foo
this bar

def bar():
    print("this bar")
def foo():
    print("this foo")
    bar()

foo()

运行结果:

this foo
this bar

为什么bar函数在前面,foo()也能调用呢?
因为代码运行是从上到下执行的,所以在开始的时候已经编译了bar()函数,所以要执行bar()函数的时候,内存里面已经有了,就能正常调用了

 

def foo():
    print("this foo")
    bar()
foo()

def bar():
    print("this bar")

 

什么叫函数的递

这样就无法运行了,会有报错:
运行结果:
NameError: name 'bar' is not defined
this foo


函数及变量,函数的存储方式就像变量一样,运行到函数的时候会编译存储到内存里面,分配内存空间,然后调用函数的时候直接去内存空间读取

 

归?

在函数内部,可以调用其他函数。如果在调用一个函数的过程中直接或间接调用自身本身这就是递归

def calc(n):
    print(n)
    if int(n / 2) == 0:
        return n
    res=calc(int(n / 2))
    return res
res=calc(10)
print(res)

运行结果:
10
5
2
1
1

递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
例子二:

list=["chen","chao","zhen","xu","zhen","zhi"]
def find_way(list):
    if len(list)==0:
        return "查无此人"
    name=list.pop(0)
    if name=="xu":
        return "找到了"
    print("这里没找到,%s 不是我们要找的,我们继续往%s下找" %(name,list))
    find=find_way(list)
    return find
check=find_way(list)
print(check)

运行结果:
这里没找到,chen 不是我们要找的,我们继续往['chao', 'zhen', 'xu', 'zhen', 'zhi']下找
这里没找到,chao 不是我们要找的,我们继续往['zhen', 'xu', 'zhen', 'zhi']下找
这里没找到,zhen 不是我们要找的,我们继续往['xu', 'zhen', 'zhi']下找
找到了

#函数名就相当于一个内存地址,即函数即变量

def name():
    print("aaa")
print(name)

运行结果:

def test1():
    print('in the test1')
def test():
     print('in the test')
     return test1

print(test)
res=test()
print(res()) #相当于执行test1()这个函数了,因为test1这个函数的内存位置赋值给了res,所以res相当于test1函数的别名

运行结果:


in the test
in the test1
None

 

#函数的作用域只跟函数声明时定义的作用域有关,跟函数的调用位置无任何关系
#优先找定义的作用域里面的变量,如果找不到就往上层找,如果找不到,一直找到最上层位置

name = 'alex'
def foo():
    name='linhaifeng'
    def bar():
        # name='wupeiqi'
        print(name)
    return bar
a=foo()
print(a)
a() #bar()

运行结果:

.bar at 0x0000000001E80D90>
linhaifeng

name='alex'
def foo():
    name='lhf'
    def bar():
        name='wupeiqi'
        def tt():
            print(name)
        return tt
    return bar
bar=foo() # return bar 返回bar这个函数的内存值
tt=bar() #调用bar这个函数,return tt 返回tt这个函数的内存值
print(tt) #打印tt这个函数的内存制
tt() #调用tt这个函数
foo()()() #括号按顺序代表函数,第一个代表foo,第二个代表bar,第三个代表tt
#亦可以理解,foo()作为第一层运行函数,因为foo()会有返回值,所以foo()的返回值加上()组成第二层运行的函数,第三层道理是是一样的

运行结果:

.bar..tt at 0x0000000002710E18>
wupeiqi
wupeiqi


推荐阅读
  • 浅谈Python3中打开文件的方式(With open)
    浅谈Python3中打开文件的方式(With open)-目录0.背景知识1.常规方式:读取文件-----open()2.推荐方式:读取文件-----WithOpen1).读取方式 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 一json文件JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。JSON采用完全独立于语言的文本格式,但是也使 ... [详细]
  • 这篇文章给大家分享的是有关python3怎样中文转换编码的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。示例:处理 ... [详细]
  • Python Flask学习之安装SQL,python3,Pycharm(网上下载安装即可)
    1,下载时更改pypi源。可以额外安装虚拟化环境:pipinstall-ihttp:pypi.douban.comsimple--trusted-hos ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
author-avatar
yangwei的马甲
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有