作用域: 变量的访问权限

  1. 全局变量 -> 全局作用域

  2. 局部变量 -> 局部作用域(比如在函数内定义的变量,只能在函数内调用)

    a = 10  # 全局变量 -> 全局作用域
    print(a) def func(): # 全局的一个函数
    b = 20 # 局部变量, 局部作用域
    print(a) # func()
    # print(b) def func3():
    func()
    func3()
  3. 如果想要在函数外面访问到函数内部的东西. 必须要return
    def func():
    c = 10086
    return c # 如果想要在函数外面访问到函数内部的东西. 必须要return c1 = func()
    print(c1)

总结: 里面访问外面没问题, 外面访问里面不能直接访问到

函数可以嵌套函数

综上:
    1, 函数可以作为返回值进行返回
    2, 函数可以作为参数进行互相传递
    函数名实际上就是一个变量名, 都表示一个内存地址

函数嵌套举例:

def func1():
b = 20
def func2(): # 函数的嵌套, 局部变量
pass
# func2 = def():
print(b)
func2() # 局部的东西. 一般都是在局部自己访问使用的 print(func1())

函数相互调用举例:

def func1():
pass def func2():
func1() # 这个叫函数间的调用. 不叫嵌套 func2()

函数互相嵌套的运行顺序

def func1():    # 2
print(123) # 3
def func2(): # 6
print(456) # 7
def func3(): # 10
print(789) # 11
print(1) # 8
func3() # 9
print(2) # 12
print(3) # 4
func2() # 5
print(4) # 13 func1() # 1 执行从这里开始 #运行结果
123
3
456
1
789
2
4

局部变量函数,要在外部使用

def func():
def inner():
print(123)
print(inner)
return inner # 返回的是一个函数, 此时我们把一个函数当成一个变量进行返回的 b1 = func() # b1是func的内部inner
print(b1)
b1() def an():
print(123)
an()
bn = an
bn()

return innerreturn inner()是不一样的

函数的实参可以是:变量

def func(an):
print("实参调用变量c") c = 123
func(c)

函数的实参可以是:函数

def func(an):    # 此时an收到的是一个函数
print(an) # 注意这里不是an() def target():
print("实参调用的是函数") func(target) # 实参是个函数 #执行结果
<function target at 0x000001F0E09116C0>

代理模式执行函数,func()本身不执行实际内部target()函数

def func(an):  # 此时an收到的是一个函数
an() # 执行这个函数 def target():
print("我是target") func(target)

Global和nonlocal

global : 在局部,指定某些全局变量引入进来

nonlocal: 在局部,引入外层的局部变量,但不能引用到全局

这样运行程序,在函数func()内部无法修改成功全局变量a的值

a = 10    # 全局变量a
def func():
a = 20 # 创建一个局部变量. 并没有去改变全局变量中的a func()
print(a) #运行结果:
10

如果此时我就想在函数内部修改全局的变量a,需要使用global

global : 在局部. 把某些全局变量引入进来

a = 10    # 全局变量a
def func():
global a # 把外面的全局变量引入到局部
a = 20 # 此时全局变量a被函数内引用,并被正确修改。
func()
print(a) # 结果为20

nonlocal: 在局部, 递进地引入外层的局部变量,但不能引用到全局

def func():
a = 10
def func2():
nonlocal a # 向外找一层. 看看有没有该变量. 如果有就引入, 如果没有, 继续向外一层, 但不能到全局
a = 20
func2()
print(a) func()

闭包:

本质, 内层函数对外层函数的局部变量的使用. 此时内层函数被称为闭包函数
    1. 可以让一个变量常驻与内存,可随时被外层函数调用。
    2. 可以避免全局变量被修改、被污染、更安全。(通过版本控制工具,将不同人所写的代码都整合的时候,避免出现问题)

def func():
a = 10
def inner():
print(a)
return a
return inner ret = func()

代码定义了一个函数 func,它返回了另一个函数 inner。这种结构被称为闭包(closure),因为 inner 函数引用了在其外部定义的变量 a。在这里,afunc 函数的局部变量,但由于 inner 函数引用了它,a 的值在 inner 函数被调用时仍然是可用的。

这段代码可以实现的特殊效果:

1、因为迟迟没有使用ret()调用retinner函数),程序为了能够持续提供可用性,会将该段代码常驻于内存。不会被内存回收。

2、用函数来定义局部变量a,并且局部变量不会被后续函数外的代码操控、改变,仅可以被赋值后读取、打印。不能被其他全局变量修改。实现局部变量仅可以在本函数内部才可以被操作。a被保护起来了。

3、想调用这个局部变量a,可以随时调用ret()函数,使得局部变量既可以被调用,还不会被修改。

未来某一时刻,ret()调用了 func 函数并将其结果赋值给变量 ret。此时,ret 包含了 inner 函数。如果你调用 ret(),它将输出 10,因为 inner 函数引用了外部的 a 变量,而 a 的值在 func 函数被调用时被设置为 10

再看下面一段代码

def func():
a = 0
def inner():
nonlocal a
a += 1
return a
return inner ret = func()
a = 20 #此时即使出现了全局变量a=20,也不会干扰到func函数局部变量a的计数器累计
# inner => ret => 什么时候执行
r1 = ret()
print(r1) #第一次输出,结果为1 # 可能1000000行后才执行 r2 = ret()
print(r2) #第二次输出,结果为2 print(ret()) #结果为3
print(ret()) #结果为4

这段代码,常驻于内存,有实现内部计数器的作用。

locals和globals

locals:函数会以字典的类型返回当前位置的所有局部变量:

globals:函数会以字典的类型返回全部局部变量:

locals:

下面这段代码:此时locals被写在了全局作用域范围内. 此时看到的就是当前作用域(全局)中的变量内容

a = 188

print(locals())  # 此时locals被写在了全局作用域范围内. 此时看到的就是当前作用域(全局)中的内容

#执行结果
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000166DC5150D0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\Python\\装饰器.py', '__cached__': None, 'a': 188}

下面这段代码:此时locals放在局部作用域范围, 看到的就是局部作用域的变量内容

a = 188

def func():
b = 336
print(locals()) # 此时locals放在局部作用域范围, 看到的就是局部作用域的内容
func() #运行结果
{'b': 336}

globals

此时globcals虽然放在局部作用域范围, 但是看到的是全局作用域的变量内容

a=188

def func():
b = 336
print(globals()) # 此时globals虽然放在局部作用域范围, 但是看到的是全局作用域的内容
func() #运行结果
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000166DC5150D0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\Python\\装饰器.py', '__cached__': None, 'a': 188, 'func': <function func at 0x00000166DC7EA020>}

globcals不论写在哪里都是全局作用于的变量内容

Python——第四章:作用域的更多相关文章

  1. 简学Python第四章__装饰器、迭代器、列表生成式

    Python第四章__装饰器.迭代器 欢迎加入Linux_Python学习群  群号:478616847 目录: 列表生成式 生成器 迭代器 单层装饰器(无参) 多层装饰器(有参) 冒泡算法 代码开发 ...

  2. Python第四章-字典

    第四章 字典-当索引不好用时 4.0     字典可以理解成是C++里的map,可以映射任何类型.字典这种结构类型称为映射(mapping).   字典是Python中唯一内建的映射类型,字典中的值并 ...

  3. Python第四章实验报告

    一.实验项目名称:<零基础学Python>第四章的14道实例和4道实战 二.实验环境:IDLE(Python 3.9 64-bit) 三.实验目的和要求:熟练掌握Python序列的应用 四 ...

  4. python第四章:函数--小白博客

    Python函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可 ...

  5. 流畅的python第四章文本和字节序列学习记录

    字符问题 把码位转化成字节序列的过程是编码,把字节序列转化成码位的过程是解码 把unicode字符串当成人类可读的文本,码位当成机器可读的, 将字节序列编程人类可读是解码,把字符串编码成字节序列是编码 ...

  6. js第四章作用域

    一.动态的属性 //创建了一个变量并且保存在了变量person中 var person = new Object(); //为该对象添加了一个名为name的属性,将字符串值‘NiCholas’赋值给n ...

  7. Python第四章(北理国家精品课 嵩天等)

    一.程序的分支结构 二.身体质量指数BMI #CalBIv1.py height,weight = eval((input("请输入身高(米)和体重\(公斤)[逗号隔开]:"))) ...

  8. Python第四章-流程控制

    流程控制 在以前的代码中,所有的代码都是交由 Python 忠实地从头执行到结束.但是这些远远不够.很多时候需要根据不同的情况执行不同的代码. 如果你想改变这一工作流程,应该怎么做? 就像这样的情况: ...

  9. Python第四章

    import datetime # 定义一个列表 mot = ["今天星期一:\n坚持下去不是因为我坚强,而是因为我别无选择.",        "今天星期二:\n含泪播 ...

  10. 分分钟钟学会Python - 第四章 文件操作

    4.1 文件基本操作 obj = open('路径',mode='模式',encoding='编码') obj.write() # 写入 obj.read() # 读取 obj.close() #关闭 ...

随机推荐

  1. 「luogu - P3911」最小公倍数之和

    link. Denote \(cnt_{x}\) = the number of occurrences of \(x\), \(h\) = the maximum of \(a_i\), there ...

  2. 「codeforces - 868F」Yet Another Minimization Problem

    link. 值域分治优化决策单调性 DP 的 trick.朴素做法 trivial,不赘述. 考虑求取一个区间 \([l,r]\) 的 DP 值.先搞定在 \(m=\lfloor\frac{l+r}{ ...

  3. MySQL PXC集群新增一个高版本节点

    已有的一个 MySQL PXC 集群环境,因为种种原因仅剩一个节点 node1,需要新增一个集群节点 node2. node1 版本:donor version (8.0.21) node2 版本:l ...

  4. Chiplet解决芯片技术发展瓶颈

    这是IC男奋斗史的第38篇原创 本文1776字,预计阅读4分钟. Chiplet封装是什么 介绍Chiplet前,先说下SOC.Chiplet和SOC是两个相互对立的概念,刚好可以用来互为参照. SO ...

  5. 小景的Dba之路--Oracle用exp导出dmp文件很慢

    小景最近在系统压测相关的工作,其中涉及了Oracle数据库相关的知识,之前考的OCP证书也在此地起了作用.今天的问题是:Oracle用exp导出dmp文件很慢,究竟是什么原因,具体的解决方案都有哪些呢 ...

  6. 从零用VitePress搭建博客教程(1) – VitePress的安装和运行

    1.从零用VitePress搭建博客说明(1) – VitePress的安装和运行 一.写在前面 最近在想更新一把自己的前端吧小博客,但发现wordPress版本停留在了5年之前,发现变化挺大,不支持 ...

  7. kubernetes组件介绍-service概念

    kubernetes组件介绍 MESOS APACHE 分布式资源管理框架 2019-5 Twitter > Kuberneets Dcocker Swarm 2019-07 阿里云宣布 Doc ...

  8. java4.switch条件语句、循环结构

    switch条件语句.循环结构 循环结构 while 1.先判断再执行代码 2.代码块至少执行0次 do-while- 1.先执行代码再执行判断 2.代码块至少执行1次 for 1.用于编写已知循环次 ...

  9. svn 分支的创建及合并

    http://blog.csdn.net/jixiuffff/article/details/5586858 http://zhidao.baidu.com/link?url=uiRk-4ZBkLPx ...

  10. 适合业余爱好者DIY的高精度数字电桥

    基本状况:工作频率: 100Hz,1kHz,7.813kHz最小分辨:最小分辨0.5毫欧,0.03uH,0.02pF最大分辨:G欧基本量程精度:1kHz基本量程精度,0.5%,选好电阻,精心制作,可以 ...