变量作用域

变量作用域

Date: 2019-05-14

Author: SunnyChou

Organization:软谋教育

变量由作用范围来限制,按照作用域分类可分为:

  • 全局(global): 在函数外部定义
  • 局部(local):在函数内部定义

1. 命名空间

​ 比如有一个学校,有5个班级,在2班和4班中都有一个叫“小明”的同学,如果在学校的广播中呼叫“小明”时,2班和4班中的这2个人就纳闷了,你是喊谁呢!!!如果是“2班的小王”的话,那么就很明确了,那么此时的2班就是小王所在的范围,即命名空间

Python中有三种命名空间

a) 局部,函数内的命名空间就是局部的;

b) 全局,模块内的命名空间就是全局的;

c) 内置,包括异常类型、内建函数和特殊方法,可以代码中任意地方调用;

命名空间特点

​ Python会把命名后的变量和函数分配到不同的命名空间,并通过名称来识别它们。

​ Python命名空间是名称到对象的映射,这就像是字典,键名是变量名,值是变量的值。

在Python程序执行过程中,会有局部命名空间、全局命名空间和内建命名空间同时存在。

​ 局部命名空间记录函数内部的变量、传入函数的参数、嵌套函数等被命名的对象;

​ 全局命名空间记录模块的变量、函数、类及其它导入的模块等被命名的对象;

locals() 和globals()

在python中,变量是以字典形式存储的存储的

globals()是全局变量; locals()则是局部变量

# -*- coding: utf-8 -*-
__author__ = 'sunnychou'
__date__ = '2019/5/18 18:35'

k = 100

def print_1():
    i = 1
    j = 2
    print('locals():', locals())
    print('globals():', globals())

print_1()

输出:

locals(): {'j': 2, 'i': 1}
globals(): {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000028171B0EFD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'F:/Tx_Project/basic_project/day02/demo/test3.py', '__cached__': None, '__author__': 'sunnychou', '__date__': '2019/5/18 18:35', 'k': 100, 'print_1': <function print_1 at 0x0000028171A12EA0>}

案例

​ 内建命名空间记录Python自身提供的函数、模块等被命名的对象。

>>> x = 3
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'x': 3, '__package__': None}

​ 可以看到变量x,3以字典的形式存放在globals空间内。以之对应的名字空间还有:locals()。

>>> locals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'x': 3, '__package__': None}

实际上,你可以通过向名字添加键名和值:

>>> globals()['y'] = 5
>>> y
5

全局变量与局部变量

全局变量是在整个py文件中声明,全局范围内都可以访问

局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地方调用, 就会出问题

全局变量与局部变量两者的本质区别就是在于作用域

2.变量作用域

作用域是针对变量而言,指申明的变量在程序里的可应用范围。或者称为变量的可见性。

按照作用域划分,可以分为:

  • L:Local,局部作用域

  • E:Enclosing,闭包作用域【闭包外的函数中定义的变量】

  • G:Global,全局作用域 在所有函数外定义的变量

  • B:Built-in,內建作用域【内置作用域】

说明

​ 一般在函数体外定义的变量成为全局变量,在函数内部定义的变量称为局部变量

​ 全局变量所有作用域都可读,局部变量只能在本函数可读

​ 函数在读取变量时,优先读取函数本身自有的局部变量,再去读全局变量

​ 全局变量在局部可以使用(即函数内部可以方位函数外部定义的变量)

案例分析

#1 局部作用域  
#局部变量只能在函数内部使用,外部无法引用
#局部变量的作用域从定义开始到函数体结束
def demo():
    num = 20  #局部变量  
    print(num)
demo()
#print(num) 错误

#函数作用域
def outter():
   x = 10   #函数作用域,从定义开始到本函数结束
   def inner():
      y = x  #在闭包中可以引用
      print(y)
   return inner
pf = outter()
pf()  #执行闭包
print(pf.__closure__)

#全局作用域
x = 100    #全局作用域  从定义开始到本文件结束
def demo():
   print(x)
print(x)

#内建作用域,是指系统内建的函数或常量,在系统载入时加载,在所有模块中都可以直接引用
#比如说系统函数
print(max(1,2,3))  #max函数就是内建作用域  哪里都可以引用
def  demo():
    x = 30
    y = 50
    print(max(x, y))

变量作用域查找规则

以 L --> E --> G -->B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,最后到内建作用域中找。

python作用域种类

问题:想想此时运行下面的程序会有输出吗?执行会成功吗?

# -*- coding: utf-8 -*-
__author__ = 'sunnychou'
__date__ = '2019/5/18 13:52'

for i in range(5):
    name = "andy"

print(name)
for i in range(10):
    age = i

print(age)

输出:

andy
9

​ 代码执行成功,没有问题;在Java/C#中,执行上面的代码会提示name,age没有定义,而在Python中可以执行成功,这是因为在Python中是没有块级作用域的,代码块里的变量,外部可以调用,所以可运行成功

(2)局部作用域

​ Python中没有块级作用域,但是有局部作用域

# -*- coding: utf-8 -*-
__author__ = 'sunnychou'
__date__ = '2019/5/18 13:52'

# 局部作用域
def func():
    name = "sunny"

print(name)

​ name变量只在func()函数内部中生效,所以在全局中是没法调用的

问题:

​ 如果在print(name)前调用func()函数呢?对结果是否有影响?

(3)闭包作用域

​ 闭包的作用域,是一个或多个命名空间按照一定规则叠加影响代码区域;运行时动态的作用域,是按照特定层次组合起来的命名空间。

# -*- coding: utf-8 -*-
__author__ = 'sunnychou'
__date__ = '2019/5/18 13:52'
i = 100

def g():
    print(i)

def f():
    i = 200
    g()

f()

上述运行结果是100

(4)全局作用域

先执行如下程序,观察结果

# -*- coding: utf-8 -*-
__author__ = 'sunnychou'
__date__ = '2019/5/18 13:52'

number = 100

def process():
    i = 5                 #局部变量,局部作用域
    number += 1
    print(f"i is {i}, number is {number}")

process()

此时会出现UnboundLocalError: local variable ‘number’ referenced before assignment错误。

问题:如何让一个函数内能访问一个全局变量呢?

# -*- coding: utf-8 -*-
__author__ = 'sunnychou'
__date__ = '2019/5/18 13:52'

number = 100

def process():
    i = 5                 #局部变量,局部作用域
    global number
    number += 1
    print(f"i is {i}, number is {number}")


process()

通过以上例子,可以知道,通过global关键字。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值