zoukankan      html  css  js  c++  java
  • Python学习笔记(九)- 变量进阶、函数进阶

    变量进阶(理解)

    在 Python 中:

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

    可变和不可变类型

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

      • 数字类型 intboolfloatcomplexlong(2.x)
      • 字符串 str
      • 元组 tuple
    • 可变类型,内存中的数据可以被修改:

      • 列表 list
      • 字典 dict
    a = 1
    a = "hello"
    a = [1, 2, 3]
    a = [3, 2, 1]
    demo_list = [1, 2, 3]
    
    print("定义列表后的内存地址 %d" % id(demo_list))
    
    demo_list.append(999)
    demo_list.pop(0)
    demo_list.remove(2)
    demo_list[0] = 10
    
    print("修改数据后的内存地址 %d" % id(demo_list))
    
    demo_dict = {"name": "小明"}
    
    print("定义字典后的内存地址 %d" % id(demo_dict))
    
    demo_dict["age"] = 18
    demo_dict.pop("name")
    demo_dict["name"] = "老王"
    
    print("修改数据后的内存地址 %d" % id(demo_dict))

    注意:

    • 字典的 key 只能使用不可变类型的数据
    • 可变类型的数据变化,是通过 方法 来实现的
    • 如果给一个可变类型的变量,赋值了一个新的数据,引用会修改:变量;不再 对之前的数据引用变量 改为 对新赋值的数据引用。

    哈希

    Python中内置函数,接收一个 不可变类型 的数据作为参数,返回 结果是一个 整数

    其作用就是提取数据的 特征码(指纹)
    相同的内容 得到 相同的结果
    不同的内容 得到 不同的结果


    在 Python 中,设置字典的 键值对 时,会首先对 key 进行 hash 已决定如何在内存中保存字典的数据,以方便 后续 对字典的操作:增、删、改、查
    键值对的 key 必须是不可变类型数据
    键值对的 value 可以是任意类型的数据

    局部变量

    • 全局变量 可变范围太大,导致程序不好维护
    • 函数执行结束后,函数内部的局部变量,会被系统回收

    局部变量的作用

    • 在函数内部使用,临时 保存 函数内部需要使用的数据
    def demo1():
    
        num = 10
    
        print(num)
    
        num = 20
    
        print("修改后 %d" % num)
    
    
    def demo2():
    
        num = 100
    
        print(num)
    
    demo1()
    demo2()
    
    print("over")

    局部变量的生命周期

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

    全局变量

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

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

    函数不能直接修改 全局变量的引用(使用赋值语句修改全局变量的值)

    num = 10
    
    
    def demo1():
    
        print("demo1" + "-" * 50)
    
        # 只是定义了一个局部变量,不会修改到全局变量,只是变量名相同而已,
    在函数内部不能直接修改全局变量的值。
    num = 100 print(num) def demo2(): print("demo2" + "-" * 50) print(num) demo1() demo2() print("over")

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

    num = 10
    
    
    def demo1():
    
        print("demo1" + "-" * 50)
    
        # global 关键字,告诉 Python 解释器 num 是一个全局变量
        global num
        # 只是定义了一个局部变量,不会修改到全局变量,只是变量名相同而已
        num = 100
        print(num)
    
    
    def demo2():
    
        print("demo2" + "-" * 50)
        print(num)
    
    demo1()
    demo2()
    
    print("over")
    View Code

    代码结构示意图如下:

    函数进阶

     假设要开发一个函数能够同时返回当前的温度和湿度,利用元组即可:

    (如果一个函数返回的是元组,括号可以省略。)

    def measure():
        """返回当前的温度"""
    
        print("开始测量...")
        temp = 39
        wetness = 10
        print("测量结束...")
    
        return (temp, wetness)
    • 在 Python 中,可以 将一个元组 使用 赋值语句 同时赋值给 多个变量
    • 注意:变量的数量需要和元组中的元素数量保持一致
    result = temp, wetness = measure()

     交换两个数字:

    # 解法 1 - 使用临时变量
    c = b
    b = a
    a = c
    
    
    # 解法 2 - 不使用临时变量
    a = a + b
    b = a - b
    a = a - b
    
    
    # 解法 3 —— Python 专有,利用元组
    a, b = b, a

    在函数内部,针对参数使用 赋值语句,不会影响调用函数时传递的 实参变量。

    无论传递的参数是 可变 还是 不可变,只要 针对参数 使用 赋值语句,会在 函数内部 修改 局部变量的引用,不会影响到 外部变量的引用

    def demo(num, num_list):
    
        print("函数内部")
    
        # 赋值语句
        num = 200
        num_list = [1, 2, 3]
    
        print(num)
        print(num_list)
    
        print("函数代码完成")
    
    
    gl_num = 99
    gl_list = [4, 5, 6]
    demo(gl_num, gl_list)
    print(gl_num)
    print(gl_list)
        
    View Code

    如果传递的参数是 可变类型,在函数内部,使用 方法 修改了数据的内容,同样会影响到外部的数据。

    def mutable(num_list):
    
        # num_list = [1, 2, 3]
        num_list.extend([1, 2, 3])
        
        print(num_list)
    
    gl_list = [6, 7, 8]
    mutable(gl_list)
    print(gl_list)
    View Code

    +=

    在 python 中,列表变量调用 += 本质上是在执行列表变量的 extend 方法,不会修改变量的引用

    但是A=A+A就是字面意思。

    def demo(num, num_list):
    
        print("函数内部代码")
    
        # num = num + num
        num += num
        # num_list.extend(num_list) 由于是调用方法,所以不会修改变量的引用
        # 函数执行结束后,外部数据同样会发生变化
        num_list += num_list
    
        print(num)
        print(num_list)
        print("函数代码完成")
    
    
    gl_num = 9
    gl_list = [1, 2, 3]
    demo(gl_num, gl_list)
    print(gl_num)
    print(gl_list)
    View Code

    缺省参数

    • 定义函数时,可以给 某个参数 指定一个默认值,具有默认值的参数就叫做 缺省参数
    • 调用函数时,如果没有传入 缺省参数 的值,则在函数内部使用定义函数时指定的 参数默认值
    • 函数的缺省参数,将常见的值设置为参数的缺省值,从而 简化函数的调用

    例如:对列表排序的方法

    gl_num_list = [6, 3, 9]
    
    # 默认就是升序排序,因为这种应用需求更多
    gl_num_list.sort()
    print(gl_num_list)
    
    # 只有当需要降序排序时,才需要传递 `reverse` 参数
    gl_num_list.sort(reverse=True)
    print(gl_num_list)
    View Code

    指定函数的缺省参数

    在参数后使用赋值语句,可以指定参数的缺省值。

    def print_info(name, gender=True):
    
        gender_text = "男生"
        if not gender:
            gender_text = "女生"
    
        print("%s 是 %s" % (name, gender_text))
    View Code

    注意:

    1. 缺省参数,需要使用 最常见的值 作为默认值!
    2. 如果一个参数的值 不能确定,则不应该设置默认值,具体的数值在调用函数时,由外界传递!
    3. 省参数的定义位置:必须保证 带有默认值的缺省参数 在参数列表末尾
      def print_info(name, gender=True, title): 

      是错误的。

    4. 在 调用函数时,如果有 多个缺省参数,需要指定参数名,这样解释器才能够知道参数的对应关系!
      def print_info(name, title="", gender=True):
          """
      
          :param title: 职位
          :param name: 班上同学的姓名
          :param gender: True 男生 False 女生
          """
      
          gender_text = "男生"
      
          if not gender:
              gender_text = "女生"
      
          print("%s%s 是 %s" % (title, name, gender_text))
      
      
      # 提示:在指定缺省参数的默认值时,应该使用最常见的值作为默认值!
      print_info("小明")
      print_info("老王", title="班长")
      print_info("小美", gender=False)

    多值参数(知道)

    多值参数 的应用会经常出现在网络上一些大牛开发的框架中,知道多值参数,有利于我们能够读懂大牛的代码。

    定义支持多值参数的函数:

    • 有时可能需要 一个函数 能够处理的参数 个数 是不确定的,这个时候,就可以使用 多值参数

      • python 中有 两种 多值参数:

        • 参数名前增加 一个 * 可以接收 元组
        • 参数名前增加 两个 * 可以接收 字典
    • 一般在给多值参数命名时,习惯使用以下两个名字

      • *args —— 存放 元组 参数,前面有一个 *
      • **kwargs —— 存放 字典 参数,前面有两个 *
    • args 是 arguments 的缩写,有变量的含义
    • kw 是 keyword 的缩写,kwargs 可以记忆 键值对参数
    def demo(num, *args, **kwargs):
    
        print(num)
        print(args)
        print(kwargs)
    
    
    demo(1, 2, 3, 4, 5, name="小明", age=18, gender=True)

    元组和字典的拆包(知道)

    • 在调用带有多值参数的函数时,如果希望:
      • 将一个 元组变量,直接传递给 args
      • 将一个 字典变量,直接传递给 kwargs
    • 就可以使用 拆包,简化参数的传递,拆包 的方式是:
      • 在 元组变量前,增加 一个 *
      • 在 字典变量前,增加 两个 *
    def demo(*args, **kwargs):
    
        print(args)
        print(kwargs)
    
    
    # 需要将一个元组变量/字典变量传递给函数对应的参数
    gl_nums = (1, 2, 3)
    gl_xiaoming = {"name": "小明", "age": 18}
    
    # 会把 num_tuple 和 xiaoming 作为元组传递个 args
    # demo(gl_nums, gl_xiaoming)
    demo(*gl_nums, **gl_xiaoming)
  • 相关阅读:
    MIne FirstBlog
    P6563 [SBCOI2020]一直在你身旁
    P6563 [SBCOI2020]一直在你身旁
    T122085 [SBCOI2020]时光的流逝
    LC 918. Maximum Sum Circular Subarray
    1026 Table Tennis
    LC 1442. Count Triplets That Can Form Two Arrays of Equal XOR
    LC 1316. Distinct Echo Substrings
    LC 493. Reverse Pairs
    1029 Median (二分)
  • 原文地址:https://www.cnblogs.com/OFSHK/p/12984376.html
Copyright © 2011-2022 走看看