6 - Python 局部变量、全局变量

return:

一个函数return之后, 那么函数体中 return 后面所有语句都不会被执行,当遇到 return,程序就会跳出函数

一个函数如果不使用return关键字来指定返回到函数调用处的值, 那么默认返回None

示例:计算任意个数的整数和

def sum_count_1(*args, **kwargs):
    """
    计算任意个数的整数和
    :param args: 接受位置参数, 保存为元祖
    :param kwargs: 接受关键字参数,保存为字典
    :return:
    """
    result = 0
    for i in args:
        result += i

    for i in kwargs.values():
        result += i

    return result   # 一个函数return之后, 那么函数体中return后面所有语句都不会被执行, 当遇到return, 程序就会跳出函数
    one_var = 10    # 不会执行


# 一个函数如果不使用return关键字来指定返回到函数调用处的值, 那么默认返回None
one_result = sum_count_1(1, 2, 3, 4, 5, 6, num1=7, num2=8, num3=9)
print(one_result)

 

作用域:局部变量、全局变量

  • 在函数体内部定义的变量, 为局部变量:所在区域为内部作用域(内部命名空间)
  • 在函数体外部定义的变量, 为全局变量:所在区域为外部作用域(外部命名空间)

函数体内部变量的查找顺序

  • 1. 当前函数内部作用域中查找有没有定义这个变量
  • 2. 会去全局作用域中查找, 如果有同名的变量, 会直接获取
  • 3. 会去系统模块

示例1:

def manual_fn1():
    """作用域"""
    # 在函数体内部定义的变量, 为局部变量:所在区域为内部作用域(内部命名空间)
    num = 1
    pass


# 在函数体外部定义的变量, 为全局变量:外部作用域(外部命名空间)
num = 10
print("old num = {},id为{}".format(num, id(num)))
manual_fn1()
print("new num = {},id为{}".format(num, id(num)))

# 执行结果:
# old num = 10,id为8791307969648
# new num = 10,id为8791307969648

示例2:

# 在函数体外部定义的变量, 为全局变量:所在区域为外部作用域(外部命名空间)
num_x = 50


def manual_fn2():
    """
    在函数体内部定义的变量, 为局部变量:所在区域为内部作用域(内部命名空间)
    函数体内部变量的查找顺序
        1. 当前函数内部作用域中查找有没有定义这个变量
        2. 会去全局作用域中查找, 如果有同名的变量, 会直接获取
        3. 会去系统模块中查找, 如果系统模块中找不到, 那么会抛出NameError异常
    """
    print("内部的num_x值为:{}\nid为: {}".format(num_x, id(num_x)))


print("外部的num_x值为:{}\nid为: {}".format(num_x, id(num_x)))
manual_fn2()
num_x = 100       # 如果全局变量在末尾,执行时会报错,因为代码是从上到下执行的

 

示例3:

  • 函数中的形参为局部变量(哪怕是与全局变量同名)
  • 在函数体内部, 给变量赋值(创建变量), 那么一定为局部变量
num_z = 520


def manual_fn4():
    # 函数中的形参为局部变量(哪怕是与全局变量同名)
    # print("内部的num_y值为:{}\nid为: {}".format(num_z, id(num_z)))
    # 在函数体内部, 给变量赋值(创建变量), 那么一定为局部变量
    num_z = 100  # 局部变量
    print("内部的num_y值为:{},id为: {}".format(num_z, id(num_z)))


print("1. 外部的num_z值为:{},id为: {}".format(num_z, id(num_z)))
manual_fn4()
print("2. 外部的num_z值为:{},id为: {}".format(num_z, id(num_z)))

执行结果:
1. 外部的num_z值为:520,id为: 34789264
内部的num_y值为:100,id为: 8791195119536
2. 外部的num_z值为:520,id为: 34789264

 

示例4:global  声明为全局变量

  • 使用global关键字之后,那么指定的变量一定为全局变量,如果全局变量本身存在(num_z)会被修改
num_z = 520


def manual_fn5():
    # 函数中的形参为局部变量(哪怕与全局变量同名)
    global num_z   # 使用global关键字之后, 那么指定的变量一定为全局变量,如果全局变量本身存在会被修改
    num_z = 100  # 全局变量
    print("内部的num_z值为:{}\nid为: {}".format(num_z, id(num_z)))


print("1. 外部的num_z值为:{}\nid为: {}".format(num_z, id(num_z)))
manual_fn5()
print("2. 外部的num_z值为:{}\nid为: {}".format(num_z, id(num_z)))

 

模块调用

  • 任意一个py文件, 都可以当做是一个模块
  • py文件的名称, 一定要符合标识符的命名规范:数字 字母 下划线,不能以数字开头
  • py文件中定义的函数、变量、类都能被其他py文件导入之后,进行调用

方法一:import

  • import 模块名
  • 可以直接通过 模块名.函数名 或者 模块名.变量名 来调用

方法二:as 取别名

  • 使用 as 给模块取别名,那么可以直接使用 别名.函数 或者 别名.全局变量 来调用
  • 使用from 模块名 import 函数名或者全局变量名 as 别名

方法三:使用from 模块名 import *       ==不推荐使用

  • 会将模块中的所有方法和全局变量全部导入
  • 那么可以直接使用导入的 函数名或者全局变量名
方法一:
import 模块名1, 模块名2
import 模块名1 as 模块别名

方法二:
from 模块名1 import 函数或者全局变量

方法三:不推荐
from 模块名1 import *

 

导入模块时需要注意的点

  • 1、如果相同的模块被导入多次,那么只有第一次会导入成功
  • 2、当前py文件中定义了与导入模块中的函数或者全局变量同名时, 会将被覆盖   把导入的模块取别名
  • 3、如果导入模块, 那么被导入模块中没有任何缩进的代码都会被识别(执行)

导入模块时导入顺序

1. python系统模块
# random time math
2. 导入第三方模块
# from openpyxl import load_workbook
3. 导入自定义模块
# from Python_0703_module_file.one_module import *

 

导入模块后,程序执行时模块的搜索顺序

  • 1. 在当前模块(py文件)进行搜索
  • 2. 会去系统模块中进行搜索

 

main方法:if __name__ == "__main__":

  • 1、python内置的程序入口的方法,可用于调试当前模块的代
  • 2、当当前模块被导入进别的模块时,在别的模块调用当前模块的方法、变量时,此时__name__变量!='__main__',__name__=='被导入模块的名称'

 

__name__变量有什么特性?

  • Python中每运行一个py文件, 都会生成一个内置的__name__变量
  • 而这个变量的值为__main__
  • 如果把它当做一个模块, 导入到其他的py文件中, 那么__name__的值为当前模块名

 

练习题:

1.函数默认返回什么值? 返回值有哪些形式? 在函数体中, return会中断循环吗?

函数默认返回什么值?

    • None

返回值有哪些形式?

    • 返回单个值
    • 返回多个值(以逗号进行分割),为元祖类型

在函数体中,return会中断循环吗?

2.局部变量和全局变量是什么? 如何在函数内部修改全局变量?

局部变量和全局变量是什么?

    • 局部变量:在内部作用域( 局部命名空间)中定义的变量
    • 全局变量:在外部作用域( 全局命名空间)中定义的变量

如何在函数内部修改全局变量?

    • 先使用global声明
    • 再对全局变量进行赋值

 

3.局部变量的搜索顺序?

  • 先局部命名空间
  • 再全局命名空间
  • 系统模块中

 

4.什么是模块?有什么作用?

什么是模块?

    • 模块 好比是 工具包
    • 每一个以扩展名 py 结尾的文件都是一个 模块
    • 全局变量 、 函数、类 都是模块能够提供给外界直接使用的工具

有什么作用?

    • 代码重用,提高工作效率
    • 让代码更简洁

 

5.模块中的哪些资源可以被调用处使用?

  • 全局变量 、 函数、类 都是模块能够提供给外界直接使用的工具

 

6.模块的命名规范

  • 由字符、数字、下划线组成
  • 不能与关键字重名
  • 不能以数字开头
  • 不能与系统内置的模块、函数、类重名
  • 建议不要以下划线开头
  • 建议不要使用中文

注意:如果在给 Python 文件起名时,以数字开头是无法在 PyCharm 中通过导入这个模块的

 

7.模块的导入方式有哪几种?

  • import 模块名1, 模块名2
    • import 模块名1 as 模块别名  
  • from 模块名1 import 函数或者全局变量
  • from 模块名1 import *

 

8.编写如下程序,从键盘获取一个数字,然后计算它的阶乘,例如输入的是3,那么即计算3!的结果,并输出

提示:

  • a. 1!等于 1
  • b. 2!等于 1*2
  • c. 3!等于 1*2*3
  • d. n!等于 1*2*3*...*n
def is_int(int_num):
    """
    检查int num是否为整数!
    """
    if isinstance(int_num, str):  # 判断是否为字符串类型
        if int_num.isdigit():
            return True
        else:
            return False
    elif isinstance(int_num, int):  # 判断是否为整数类型
        return True
    else:
        return False


def count_factorial(one_num):
    """
    count one_num's fatorial数阶乘
    """
    result = 1
    if one_num < 0:
        print("{}为负数,没有阶乘!".format(one_num))
        return None
    elif one_num in (0, 1):
        return 1
    else:
        for i in range(1, one_num + 1):
            result *= i
        return result


input_num = input("请输入一个正整数:")
if is_int(input_num):
    input_num = int(input_num)
    print("{}的阶乘为:{}".format(input_num, count_factorial(input_num)))
else:
    print("输入的{}有误,请输入一个正整数!".format(input_num))

 

9.编写如下程序,a.在一个模块中,定义求圆的面积和周长、长方形的面积和周长的函数,然后分别在另一个程序中调用

  • b.使用多种方式导入模块
创建homework_0701目录,在其中创建calculate_perimeter_area.py文件
import math


def circle_area(r):  # 园 面积
    """
    圆 面积
    :param r: 半径
    :return: 面积
    """
    area = math.pi * (r ** 2)   # 计算圆的面积
    area = round(area, 3)       # 四舍五入,保留三位小数
    return area


def circle_perimeter(r):
    """
    圆 周长
    :param r:半径
    :return: 周长
    """
    perimeter = 2 * math.pi * r  # 计算圆的周长
    perimeter = round(perimeter, 3)     #四舍五入,保留三位小数
    return perimeter


def rectangle_area(length, width):
    """
    长方形 面积
    :param length: 长度
    :param width:宽度
    :return:面积
    """
    area = length * width       # 长方形面积
    area = round(area, 2)       # 四舍五入,保留两位小数
    return area


def rectangle_perimeter(length, width):
    """
    计算长方形周长
    :param length: 长度
    :param width: 宽度
    :return: 周长
    """
    perimeter = 2 * (length + width)  # 长方形周长
    perimeter = round(perimeter, 2)   # 四舍五入,保留三位小数
    return perimeter


if __name__ == "__main__":
    # 此处用于测试函数
    radius = float(input("请输入圆的半径(数字):"))
    print("半径为{:.2f}的圆,面积为{}, 周长为{}\n".format(radius,circle_area(radius), circle_perimeter(radius)))
    rectangle_len = float(input("请输入长方形的长度(数字):"))
    rectangle_width = float(input("请输入长方形的宽度(数字):"))
    params = (rectangle_len, rectangle_width,
              rectangle_area(rectangle_len, rectangle_width),
              rectangle_perimeter(rectangle_len, rectangle_width))
    print("长为{:.2f}, 宽为{:.2f}的长方形,面积为{}, 周长为{}。".format(*params))

在homework_0701目录中创建module_import.py文件

# from homework_0701.calculate_perimeter_area import *
from homework_0701.calculate_perimeter_area import (circle_area, circle_perimeter, rectangle_area,
                                                    rectangle_perimeter, )
# 其他文件调用
# 此处用于测试函数

radius = float(input("请输入圆的半径(数字):"))
print("半径为{:.2f}的圆,面积为{}, 周长为{}\n".format(radius, circle_area(radius), circle_perimeter(radius)))

rectangle_len = float(input("请输入长方形的长度(数字):"))
rectangle_width = float(input("请输入长方形的宽度(数字):"))

params = (rectangle_len, rectangle_width, rectangle_area(rectangle_len, rectangle_width),
          rectangle_perimeter(rectangle_len, rectangle_width))
print("长为{:.2f}, 宽为{:.2f}的长方形,面积为{}, 周长为{}。".format(*params))

 

10.编写如下程序,裴伯拉切数列,从第三个元素开始,每个元素为前两个元素之和,用户输入某个大于0的正整数,求出小于等于这个正整数的所有裴伯拉切元素

  • a.裴伯拉切数列为:0 1 1 2 3 5 8 13 21 34 55 89 144 ...
  • b.例如,用户输入50,那么小于等于50的裴伯拉切元素为:0 1 1 2 3 5 8 13 21 34
  • c.要求在一个模块中定义,在另一个程序中调用

1.在homework_0701中创建calculate_fifibonacci.py文件

def fibo(n):
    """
    计算小于等于n的所有裴伯拉切元素
    :param n:
    :return:
    """
    if n < 0:
        print("您输入的是{},请输入一个正整数!".format(n))
        return None
    if n == 0:
        print(0)
        return None

    a, b = 0, 1
    while a < n:
        print(a, end=" ")
        a, b = b, a + b
    print()


if __name__ == '__main__':
    # 此处为测试代码
    num_n = int(input("请输入一个正整数:"))
    fibo(num_n)

2.在homework_0701中创建module_import_fifib.py文件

from homework_0701 import calculate_fibonacci as cal_fib
if __name__ == '__main__':
    num_n = int(input("请输入一个正整数:"))
    cal_fib.fibo(num_n)
    
    # 执行结果
    # 请输入一个正整数:22
    # 0 1 1 2 3 5 8 13 21

 

 

*******请大家尊重原创,如要转载,请注明出处:转载自:https://www.cnblogs.com/shouhu/,谢谢!!******* 

posted @ 2020-04-09 08:34  守护往昔  阅读(459)  评论(0编辑  收藏  举报