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/,谢谢!!*******
本文仅供参考;如果这篇文件对你有所帮助,麻烦动动发财的小手,推荐一波支持下万分感谢
*******请大家尊重原创,如要转载,请注明出处:作者:守护@往昔;转载自:https://www.cnblogs.com/shouhu/,谢谢!!*******