1. 变量的引用

  • 变量 和 数据 都是保存在 内存 中的
  • Python函数 的 参数传递 以及 返回值 都是靠 引用 传递的

1.1 引用的概念

Python

  • 变量数据 是分开存储的
  • 数据 保存在内存中的一个位置
  • 变量 中保存着数据在内存中的地址
  • 变量记录数据的地址,就叫做 引用
  • 使用 id() 函数可以查看变量中保存数据所在的 内存地址

注意:如果变量已经被定义,当给一个变量赋值的时候,本质上是 修改了数据的引用

  • 变量 不再 对之前的数据引用
  • 变量 改为 对新赋值的数据引用

1.2 变量引用 的实例

  • ipython3 中,定义两个变量ab,并使用 id()函数查看其内存地址。

  • 如下图,标示出了变量和数据的应用关系:

  • 编写代码来说明


a = 1 print("a的内存地址是:%d" % id(a)) b = 2 print("b的内存地址是:%d" % id(b)) c = 2
print("c的内存地址是:%d" % id(c))

1.3 函数的参数和返回值的传递

Python 中,函数的 实参/返回值 都是是靠 引用 来传递来的,写了小的例子尝试下:

def test(num):

    print("-" * 50)
print("%d 在函数中的内存地址是 %d" % (num, id(num))) result = 12 print("返回值 %d 在内存中的地址是 %d" % (result, id(result)))
print("-" * 50) return result n = 100 print("%d在调用之前的内存地址是%d" % (n, id(n))) r = test(n) print("调用函数后,实参 %d 的内存地址是 %d" % (n, id(n)))
print("调用函数后,返回值 %d 的内存地址是 %d" % (r, id(r)))

2. 可变和不可变类型

  • 不可变类型,内存中的数据不允许被修改:

    • 数字类型 int, bool, float, complex, long(2.x)
    • 字符串 str
    • 元组 tuple
  • 可变类型,内存中的数据可以被修改:
    • 列表 list
    • 字典 dict

注意

  1. 可变类型的数据变化,是通过 方法 来实现的
  2. 如果给一个可变类型的变量,赋值了一个新的数据,引用会修改
    • 变量 不再 对之前的数据引用
    • 变量 改为 对新赋值的数据引用

哈希 (hash)

  • Python 中内置有一个名字叫做 hash(o) 的函数

    • 接收一个 不可变类型 的数据作为 参数
    • 返回 结果是一个 整数
  • 哈希 是一种 算法,其作用就是提取数据的 特征码(指纹)
    • 相同的内容 得到 相同的结果
    • 不同的内容 得到 不同的结果
  • Python 中,设置字典的 键值对 时,会首先对 key 进行 hash 已决定如何在内存中保存字典的数据,以方便 后续 对字典的操作:增、删、改、查
    • 键值对的 key 必须是不可变类型数据
    • 键值对的 value 可以是任意类型的数据

例子:

3. 局部变量和全局变量

  • 局部变量 是在 函数内部 定义的变量,只能在函数内部使用
  • 全局变量 是在 函数外部定义 的变量(没有定义在某一个函数内),所有函数 内部 都可以使用这个变量

提示:在其他的开发语言中,大多 不推荐使用全局变量 —— 可变范围太大,导致程序不好维护!

3.1 局部变量

  • 局部变量 是在 函数内部 定义的变量,只能在函数内部使用
  • 函数执行结束后,函数内部的局部变量,会被系统回收
  • 不同的函数,可以定义相同的名字的局部变量,但是 彼此之间 不会产生影响

局部变量的作用

  • 在函数内部使用,临时 保存 函数内部需要使用的数据
def test1():

    num = 1

    print(num)

    num = 22

    print("修改过后 %d" % num)

def test2():

    num = 30

    print(num)

test1()
test2() print("结束")

局部变量的生命周期

  • 所谓 生命周期 就是变量从 被创建被系统回收 的过程
  • 局部变量函数执行时 才会被创建
  • 函数执行结束后 局部变量 被系统回收
  • 局部变量在生命周期 内,可以用来存储 函数内部临时使用到的数据

3.2 全局变量

  • 全局变量 是在 函数外部定义 的变量,所有函数内部都可以使用这个变量
num = 10

def test1():

    print(num)

def test2():

    num = 22

    print(num)

test1()
test2() print(num)

注意:函数执行时,需要处理变量时 会:

  1. 首先 查找 函数内部 是否存在 指定名称 的局部变量如果有,直接使用
  2. 如果没有,查找 函数外部 是否存在 指定名称 的全局变量如果有,直接使用
  3. 如果还没有,程序报错!

1) 在函数中不能直接修改 全局变量的引用

  • 全局变量 是在 函数外部定义 的变量(没有定义在某一个函数内),所有函数 内部 都可以使用这个变量

提示:在其他的开发语言中,大多 不推荐使用全局变量 —— 可变范围太大,导致程序不好维护!

  • 在函数内部,可以 通过全局变量的引用获取对应的数据
  • 但是,不允许直接修改全局变量的引用 —— 使用赋值语句修改全局变量的值
num = 10

def test1():

    print("test1" + "*" * 50)

    num = 100

    print(num)

def test2():

    print("test2" + "*" * 50)

    print(num)

test1()
test2() print("over")

注意:只是在函数内部定义了一个局部变量而已,只是变量名相同 —— 在函数内部不能直接修改全局变量的值

2) 在函数内部修改全局变量的值

  • 如果在函数中需要修改全局变量,需要使用 global 进行声明
num = 10

def test1():

    print("test1" + "*" * 50)

    global num
num = 100 print(num) def test2(): print("test2" + "*" * 50) print(num) test1()
test2() print("over")

3) 全局变量定义的位置

  • 为了保证所有的函数都能够正确使用到全局变量,应该 将全局变量定义在其他函数的上方
a = 1

def test():

    print(a)
print(b)
print(c) b = 2
test()
c = 3

注意

  • 由于全局变量 c,是在调用函数之后,才定义的,在执行函数时,变量还没有定义,所以程序会报错!

4) 全局变量命名的建议

  • 为了避免局部变量和全局变量出现混淆,在定义全局变量时,有些公司会有一些开发要求,例如:
  • 全局变量名前应该增加 g_ 或者 gl_ 的前缀

提示:具体的要求格式,各公司要求可能会有些差异

gl_num = 33
gl_name = "zfx" def test(): num = 10 print(num)
print(gl_name) test()

python基础学习(十二)变量进阶的更多相关文章

  1. Python基础学习(二)

    前一段时间学习了Python数据类型,语句和函数,目前书写python的新特性,继续练手!!!! 一.切片 之前我们从python的list 或者 tuple中取得元素都是这样写,显然不够灵活 lis ...

  2. python基础学习十 logging模块详细使用【转载】

    很多程序都有记录日志的需求,并且日志中包含的信息既有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,主要用于输出 ...

  3. Py修行路 python基础 (十二) 协程函数应用 列表生成式 生成器表达式

    一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._next_() 取下一个值 优点: 1.提供了 ...

  4. Python基础(十二)

    今日主要内容 推导式 生成器表达式 lambda匿名函数 内置函数介绍 一.推导式 (一)列表推导式 先来看一段代码 建立一个空列表,向空列表中添加元素 lst = list() for i in r ...

  5. python基础学习2 函数变量与赋值

    学习的第一步,就是通常的输出函数:print() 1.基础主要学习了变量的赋值,变量名可以疑字母.数字.下划线(_)进行命名,但是不能以数字开头 变量的赋值:变量名 = 变量值 2.模块的导入,和调用 ...

  6. Python基础学习总结(二)

    2.列表简介 Python有内置的一种数据类型列表:list. list是一种有序的集合. 列表由一系列按特定顺序排列的元素组合.用方括号 [ ] 来表示. list里面的元素的数据类型可以不同,比如 ...

  7. python基础(十二)--模块

    模块的导入方式 import os  调用时os.rename from os import rename #只导入的特定功能 调用时rename() from asynico.events impo ...

  8. python基础学习(二)--函数

    return返回值: python函数都有返回值,函数体内无return,默认返回值None, 函数参数: 1.普通参数 严格按照顺序,将实际参数赋值给形式参数,一一对应. 例: def send(x ...

  9. python基础学习笔记二之列表

    1.列表 ①列表的创建: ②列表的查询(索引): ③列表的切片操作: 此处要注意到:返回索引0到3的元素,顾头不顾尾. ④列表的增加: s.append()  #直接在结尾追加 s.insert()  ...

  10. Python基础学习篇章二

    一. Python如何运行程序 1. 在交互模式下编写代码 最简单的运行Python程序的方法是在Python交互命令行中输入程序.当然有很多方法可以开始这样的命令行,比如IDE,系统终端.如果你已经 ...

随机推荐

  1. Tomcat 部署项目无法加载静态资源

    首先,我的Eclipse是引用外部的Tomcat 引用外部Tomcat会在左侧生成一个Server文件夹,相当于复制了一份Tomcat到Eclipse的安装目录里 具体Tomcat所在目录可以在这进行 ...

  2. 电商门户网站商品品类多级联动SpringBoot+Thymeleaf实现

    在淘宝.京东等电商网站,其门户网站都有一个商品品类的多级联动,鼠标移动,就显示,因为前端不是我做的,所以不说明前端实现,只介绍后端实现. 搭建部署SpringBoot环境 配置文件配置: 开启了对Th ...

  3. MySQL:数据库表的空间回收

    1. 表数据的存储方式 表数据既可以存储在共享表空间,也可以时单独的文件.这个行为由参数 innodb_file_per_table 控制: 设置为 OFF 时,表示表数据存储在共享表空间: 设置为 ...

  4. git gc和fsck的用法

    一.保证git良好的性能 在大的仓库中, git靠压缩历史信息来节约磁盘和内存空间. 压缩操作并不是自动进行的, 你需要手动执行 git gc: $ git gc 压缩操作比较耗时, 你运行git g ...

  5. Python中高级变量类型(列表,元组,字典,字符串,公共方法...)

    高级变量类型 目标 列表 元组 字典 字符串 公共方法 变量高级 知识点回顾 Python 中数据类型可以分为 数字型 和 非数字型 数字型 整型 (int) 浮点型(float) 布尔型(bool) ...

  6. Swift中空合运算符、闭区间运算符、单侧区间、半开区间

    空合运算符(Nil Coalescing Operator) 用于取代3目判空运算,提供超短的写法比如常规判空写法如下,反正我写java就是这么干的 var anOptionalInt: Int? = ...

  7. 数据库占用cpu较高的查询

    近来看到别人的有关数据库查询cpu占用较高的sql语句(本人sql并不好),所以查询了一下资料,记录一下,便于理解和应用. 首先,将语句贴在这里 SELECT TOP 10 --平均cpu时间 tot ...

  8. odoo开发笔记--from视图隐藏顶部&tree视图保留

    场景描述: 开发过程中,有时候我们需要去除odoo自带的一些样式, 比如,form视图,要集成自定义的界面时,就希望把顶部的服务动作 和 分页按钮 隐藏掉. 处理方式: 分两种情况: 1. 保留顶部区 ...

  9. 使用Docker发布DNC项目

    项目结构 可以忽略中间三个Console项目 ApiCenter 是一个WebAPI项目,引用了NLog.MQ项目 ApiCenter使用5001端口 public static IWebHost B ...

  10. mysql 开发进阶篇系列 20 MySQL Server(innodb_lock_wait_timeout,innodb_support_xa,innodb _log_*)

    1. innodb_lock_wait_timeout mysql 可以自动监测行锁导致的死锁并进行相应的处理,但是对于表锁导致的死锁不能自动监测,所以该参数主要用于,出现类似情况的时候等待指定的时间 ...