python中数据的作用域

news2024/11/17 3:26:22

一、命名空间

        在 Python 中,命名空间是一个系统,它用于确保名字的唯一性,并防止命名冲突。命名空间是一个存储变量名称(或者更广泛地说,标识符)与对象之间映射的抽象概念。每个变量名你在程序中创建(或者导入)都存储在一个命名空间内。

1.1 类型的命名空间

        Python 中有几种不同类型的命名空间:

  1. 局部命名空间(Local Namespace):在函数内部创建的命名空间。它是临时的,每当函数被调用时创建,并在函数返回结果后销毁。这意味着,函数内部的变量名称在函数外部是不可见的。

  2. 全局命名空间(Global Namespace):在 Python 脚本的最顶层或模块层定义的变量存在于全局命名空间中。这个命名空间在脚本执行时创建,并在脚本执行结束后销毁。

  3. 内建命名空间(Built-in Namespace):Python 语言的一部分,包含了 Python 的内置函数和异常,比如 print(), id(), Exception 等。这个命名空间在 Python 解释器启动时创建,并在解释器关闭时销毁。

1.2 命名空间的寿命

  • 局部命名空间的寿命通常与函数执行的时间一致。
  • 全局命名空间的寿命通常与脚本执行的时间一致。
  • 内建命名空间的寿命通常与 Python 解释器的运行时间一致。

1.3 访问和修改命名空间

  • 使用赋值语句在相应的命名空间创建新的名称或修改现有名称。
  • 使用 global 关键词在局部作用域内操作全局命名空间的名称。
  • 使用 nonlocal 关键词修改闭包作用域中的变量。

1.4 命名空间的搜索顺序

        当你尝试访问一个变量时,Python 会按照 L-E-G-B(局部 ->嵌套 -> 全局 -> 内建)的顺序搜索这些命名空间。这个顺序确保了局部变量可以覆盖同名的全局变量或内建函数。

x = 'global x'  # 全局命名空间

def test():
    y = 'local y'  # 局部命名空间
    print(y)
    print(x)  # 无局部变量 x,向上查找到全局命名空间

test()

# print(y)  # 错误,y 在全局命名空间不可见
print(x)  # 正确,x 在全局命名空间中

1.5 总结

        理解命名空间对于有效地组织代码和避免可能的名称冲突至关重要。命名空间的概念支持了 Python 中的作用域规则,帮助开发者写出更清晰、更健壯的程序。

二、L-E-G-B 规则

        在 Python 中,变量的作用域定义了在程序的哪个部分你可以访问这个变量。Python 中的作用域主要分为四类:Local、Enclosing、Global 和 Built-in,这也是通常所说的 L-E-G-B 规则。这也是Python 的变量名解析机制。

local(本地):理解为function,即作用域为函数内部
Enclosed(嵌套):理解为Enclosing function locals,即作用域为外部嵌套函数
Global(全局):理解为module,即作用域为模块
Built-in(内置):即作用域为Python内置模块

2.1 Local(局部作用域)

  • 局部作用域是指在函数内部定义的变量。这些变量只能在其被定义的函数内部访问,函数外部是无法访问的。

def func():
    x = 10  # 局部变量
    print(x)  # 输出 10

func()
print(x)  # 这里会引发错误,因为 x 在这里是不可见的

2.2 Enclosing(闭包作用域)

  • 当你有一个定义在另一个函数内部的函数时,内部函数的作用域会被视为闭包作用域。这意味着内部函数可以访问其外层(非全局)函数的变量。

def outer():
    x = '外部 x'

    def inner():
        nonlocal x  # 使用 nonlocal 关键字声明 x 不是局部变量
        x = '内部 x'
        print(x)

    inner()
    print(x)

outer()

2.3 Global(全局作用域)

  • 全局变量是在函数外部定义的,并且在程序的多个地方都可以访问。如果你需要在函数内修改全局变量,需要用到 global 关键字。

x = 5  # 全局变量

def func():
    global x
    x = 10  # 修改全局变量 x
    print(x)  # 输出 10

func()
print(x)  # 输出 10

2.4 Built-in(内建作用域)

  • Python 本身预定义的命名空间,包含了内建的函数和异常处理等,例如 print(), len() 这些可以在程序任何地方直接调用的。

print = 5
print(print)  # 这将会导致错误,因为我们覆盖了内建的 print 函数

2.5 注意事项

  • 尽量避免在局部作用域中重定义全局变量或内建标识符,这可能会导致难以追踪的错误。
  • 使用 globalnonlocal 可以修改外层作用域中的变量,但应谨慎使用,因为它们可能使代码难以理解和维护。
  • 了解和遵守作用域规则有助于编写更清晰、更可靠的代码。

三、python项目的组织结构

         在 Python 中,包、模块和类是组织代码的基本单位,每个单位承担不同的角色,以支持更大的应用程序结构。理解这三者之间的区别和联系是非常重要的,特别是在设计大型软件系统时。以下是对每个概念的详细解释:

3.1 模块 (Module)

        模块是 Python 编程中的基本组织单位,是一个包含 Python 代码的文件(通常以 .py 结尾)。模块可以包含函数、类、变量定义以及可执行代码。模块的主要目的是帮助你逻辑地组织你的 Python 代码。模块可以被其他模块导入,以使用其功能,这可以通过 import 语句实现。

        例如,创建一个名为 calculator.py 的模块,其中包含一些基本的数学操作:

# calculator.py

def add(x, y):
    return x + y

def subtract(x, y):
    return x - y

        你可以在另一个文件中导入这个模块并使用其函数:

# main.py
import calculator

result = calculator.add(5, 3)
print(result)  # 输出 8

3.2 包 (Package)

        包是一种将多个模块组织在一起的方式,本质上是一个包含多个模块的目录,该目录中包含一个特殊的文件 __init__.py。这个文件可以为空,但它必须存在于目录中,以便 Python 将该目录视为一个包(Python 3.3 之后可以没有 __init__.py 文件,但推荐保留以保持向后兼容性)。

        包可以有多级结构,即包内可以包含子包。这种结构有助于组织大型项目。

        例如,一个名为 mathematics 的包可能结构如下:

mathematics/
│
├── __init__.py
├── algebra.py
└── calculus.py

3.3 类 (Class)

        类是面向对象编程的基本构建块。Python 中的类提供了一种将数据和功能绑定在一起的方法。通过类定义,你可以创建自己的对象类型,并在这些对象中封装数据属性(变量)和方法(函数)。

        例如,定义一个简单的类 Point,表示二维空间中的点:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def distance_to_origin(self):
        return (self.x**2 + self.y**2) ** 0.5

        创建并使用 Point 类的对象:

p = Point(3, 4)
print(p.distance_to_origin())  # 输出 5.0

3.4 组织结构示例

        假设你有以下目录结构:

myproject/
│
├── main.py
├── database.py
│
└── package/
    ├── __init__.py
    ├── module1.py
    └── subpackage/
        ├── __init__.py
        └── module2.py

 在这个结构中:

  • main.pydatabase.py 是同级的模块。
  • package 是一个包,包含一个子模块 module1.py
  • subpackage 是一个子包,包含另一个模块 module2.py

main.py 导入 module1.py

from package import module1

 从 module1.py 导入 module2.py(使用相对导入)

from .subpackage import module2

        在 Python 中,包和模块的层次结构有助于维护大型项目的组织和清晰性。理解如何在工程中组织 .py 文件和它们之间的关系是高效利用 Python 编程的关键部分。 

3.5 总结

  • 模块:单个文件,包含相关的代码。
  • :包含多个模块的文件夹,有助于进一步组织大型代码库。
  • :定义新类型的方式,封装数据和功能。

四、工程中的作用域

        在 Python 中,处理包、模块和类的作用域涉及理解如何在这些不同的代码结构之间共享和隔离数据。这里的作用域管理主要是通过模块和类的导入机制以及类内部的作用域规则来实现的。下面详细解释这些概念:

4.1 模块作用域

        每个 Python 文件(模块)本质上是一个独立的命名空间,这意味着在一个模块中定义的所有变量、函数、类等都是局限于该模块内的。如果你需要在一个模块中访问另一个模块定义的变量或函数,你需要显式地导入那个模块。

# module1.py
my_var = "Hello"

def print_hello():
    print(my_var)

# main.py
import module1

module1.print_hello()  # 正确调用
print(module1.my_var)  # 正确访问

        在这种情况下,module1.py 中的 my_varprint_hello() 只能通过导入 module1 模块后使用模块名作为前缀来访问。

4.2 包的作用域

        包是一种组织多个模块的方式,它自身也遵循模块化的作用域规则。包内的模块必须通过相对或绝对导入来相互访问。包的结构可以帮助封装功能并防止命名冲突。

# package/module1.py
def func():
    print("Function in module1")

# package/module2.py
from .module1 import func

func()  # 调用 package/module1.py 中的 func 函数

        在这里,module2.py 需要访问同一包内的 module1.py 中的函数,这是通过相对导入完成的。

4.3 类的作用域

        类定义其自身的命名空间,类中定义的变量和函数(方法)是局限于该类的。只有通过该类(或其实例)可以访问这些方法和属性。

        例如:

class MyClass:
    class_var = 10  # 类变量

    def __init__(self, value):
        self.instance_var = value  # 实例变量

    def method(self):
        return self.instance_var + MyClass.class_var

obj = MyClass(20)
print(obj.method())  # 访问方法和变量

        在这个例子中,class_var 是一个类变量,对所有实例共享,而 instance_var 是每个类实例特有的。类的方法如 method 只能通过类的实例来访问。

4.4 总结

        在 Python 中,模块、包和类的作用域管理确保了代码的封装性和命名空间的独立性。这些机制有助于创建结构化和易于维护的代码库。正确理解和利用这些作用域规则是高效使用 Python 的关键。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1858846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis-数据类型-zset

文章目录 1、查看redis是否启动2、通过客户端连接redis3、切换到db4数据库4、将一个或多个member元素及其score值加入到有序集key当中5、升序返回有序集key6、升序返回有序集key,让分数一起和值返回的结果集7、降序返回有序集key,让分数一起和值返回到结…

Android上编译和使用curl

1 概述 Android系统编译的时候默认是没有带curl工具的,但是在aosp源码中,却是有curl的源码包含。所以只需要编译curl,然后将其push到Android设备中,就可以使用curl命令了。 2 编译curl 这里编译curl是在整机代码环境下进行编译…

机器人控制系列教程之雅可比矩阵和奇异性

简介 在机器人学和控制理论中,雅可比矩阵扮演着至关重要的角色。它是一个描述机器人末端执行器速度与关节速度之间关系的数学工具。通过雅可比矩阵,我们可以更好地理解和控制机器人的运动,特别是在执行精确操作时。雅可比矩阵的计算通常基于…

python turtle 画帕恰狗

先上个图给大家看看 代码 ##作者V w1933423 import turtle turtle.bgcolor("#ece8dc") turtle.setup(600,900) p turtle.Pen() p.pensize(14) p.speed(5) p.color("black")p.penup() p.goto(-54,-44) p.pendown() p.goto(-37,-39) p.goto(-27,-24) p.go…

swp添加池子addLiquidity失败

案发现场 首次添加交易对、一直失败、但是也没提示具体的原因。到这一步就没了、由下图可知、也没看到log、由此可见第一步就失败了。 解决方案 工厂KywFactory 添加如下 bytes32 public constant INIT_CODE_PAIR_HASH keccak256(abi.encodePacked(type(KywPair).creatio…

0620所学——环境变量、CMake等

https://www.cnblogs.com/bravesunforever/p/10939078.html CMake: https://zhuanlan.zhihu.com/p/659412062 0621: 学会了在Github里创建组织,把本地仓库“同步”,就可以上传到Github,然后学会了把自己的Repos转移到组织里。G…

前端中的深拷贝

第1部分:引言 深拷贝:前端开发的隐形守护者 在前端开发的世界里,数据的传递和状态的管理是构建用户界面的基础。然而,数据的复制常常被忽视,直到它引发bug,我们才意识到它的重要性。深拷贝,这…

NC--介绍-未加密加密后-流量抓包对比

免责声明:本节仅做技术交流与学习... 目录 介绍: 用法: 未加密--流量抓包 加密: 攻击端 靶机 抓包分析: 介绍: nc 是一个Linux环境下常用的工具命令,可以用来帮助开发者查询和解决网路问题,通常被认为是 NetCat 工具的缩写,在网络工具…

arduino按钮

Arduino - Button Arduino - 按钮 参考: ezButton-按钮库从按钮开关看上拉pull-up电阻、下拉电阻按键的防抖动处理 The button is also called pushbutton, tactile button or momentary switch. It is a basic component and widely used in many Arduino projec…

06 - matlab m_map地学绘图工具基础函数 - 绘制海岸线

06 - matlab m_map地学绘图工具基础函数 - 绘制海岸线 0. 引言1. 关于m_coast2. 关于m_gshhs3. 关于m_gshhs_c、m_gshhs_I、m_gshhs_i、m_gshhs_h、m_gshhs_f4. 关于m_shaperead5. 结语 0. 引言 本篇介绍下m_map中添加绘制海岸线的一系列函数及其用法,主要函数包括m…

分享一个解决 EF 性能低的思路,通过 Python 访问心跳侦测 API 保持 EF 在线

前言 .NET FrameWork EF(Entity Framework)是一个很优秀的 ORM 框架,对于提高工作效率很有帮助,但由于底层原因,在程序启动时,EF 需要初始化和加载模型及其对应的数据库元数据等等,涉及到数据库…

分布式数据库垂直分片如何计算?

在复习分布式数据库这一部分时,发现垂直分片较难理解,上网上查找资料,也发现找不到,固在考试结束后将自己的理解记录下来。 垂直分片的计算总体上分为三个步骤;1、属性亲和度矩阵AA的计算;2、聚类亲和度CA矩阵的计算&a…

“了解MySQL中的enum枚举数据类型“

目录 # 开篇 1. 创建包含枚举类型的表 2. 插入枚举类型的数据 3. 查询包含枚举类型的表 4. 更新枚举类型的数据 5. 使用枚举类型的好处 注意事项 示例总结 附加 # 开篇 在数据库中,枚举(ENUM)是一种数据类型,用于存储一组…

vue3 运用高德地图 自定义弹框 为信息窗体 添加 new AMaps.value.InfoWindow 添加事件

效果图 划过散点的时候出现每个三点位置的数据提示 点击具体散点获取展示信息弹框,并为其添加点击事件 注意点: 1 即使是用的vue,也不能使用click为窗体添加点击事件,需要使用onclick, (原因&#xff1a…

Android 13 创建静态快捷方式shortcuts

参考 创建快捷方式 原生系统上&#xff0c;长按应用图标显示快捷方式&#xff0c;点击快捷方式就打开应用的某个页面。 给自己的应用也加一下。 1.清单文件添加 在应用的主页面添加如下&#xff0c;shortcuts 就是要配置的文件。 <meta-dataandroid:name"android.…

01 Swift 基础语法(变量,常量,注释,整数,浮点数,元组)

Swift 介绍 Swift 是一门用于开发 iOS、macOS、watchOS 和 tvOS 应用的新编程语言。它以安全、快速和互动的特点而著称。Swift 提供了代码预览&#xff08;playgrounds&#xff09;功能&#xff0c;使程序员可以在不编译和运行应用程序的情况下&#xff0c;实时运行 Swift 代码…

多模态-大模型:MLLM综述(适用初学)

文章目录 前言一、多模态模型基础知识二、多模态指令调优&#xff08;M-IT&#xff09;1.MLLM基础2.模态对齐3.数据获取4.模态桥接 三、多模态上下文学习&#xff08;M-ICL&#xff09;三、多模态思维链 (M-CoT)四、LLM辅助视觉推理1.训练范式2. LLM功能 五、一些思考总结 前言…

索引的分类和回表查询——Java全栈知识(29)

索引的分类和回表查询 Mysql 的索引按照类型可以分为以下几类&#xff0c;但是我们使用的 InnoDB 只支持主键索引&#xff0c;唯一索引&#xff0c;普通索引&#xff0c;并不支持全文索引。 1、聚集索引和二级索引 InnoDB 可以将索引分为两类分别是聚集索引和二级索引&…

模板匹配算法:基于模板相关性匹配的手写数字识别

1 前言 得益于硬件技术的发展&#xff0c;基于深度学习的各种识别方法如火如荼&#xff0c;在各种应用场景中都取得很好的效果。本人入行深度学习领域若干年&#xff0c;做过很多项目的工程化评估&#xff0c;对于神经网络是如何工作的也解释不清楚&#xff0c;只是知道这样做是…

如何借用物联网快速实现高标准农田信息化

如何借用物联网快速实现高标准农田信息化 高标准农田信息化&#xff0c;作为现代农业发展的重要基石&#xff0c;是指在建设高产、稳产、节水、环保的农田基础上&#xff0c;深度融合现代信息技术&#xff0c;实现农田管理的精准化、智能化和高效化。物联网&#xff08;Intern…