一、变量的作用域
- 变量在程序中能够使用的范围
- 1.全局变量
a.声明在函数或者类的外部的变量都是全局变量
b.全局变量是从声明开始到整个py文件结束,任何位置都可以使用(作用域:从声明开始到文件结束) - 2.局部变量
a.声明在函数或者类的里面的变量都是局部变量
b.局部变量是从声明开始到函数结束,任何位置都可以使用(作用域:从声明开始到函数结束)
# ===========1.全局变量===========
# 全局变量
a = 10
# x和y是全局变量
for x in range(10):
y = 20
print(x)
print(x, y)
if True:
# b是全局变量
b = 20
print(b)
def func1():
print('函数中:', a)
print('函数中', x, y)
# ============2.局部变量=============
# num1, num2, aa, xx都是局部变量
def func2(num1, num2):
print(num1, num2)
aa = 11
print(aa)
for xx in range(5):
print(xx)
print(xx)
- global关键字只能在函数中使用,作用是在函数中声明一个全局变量
- 语法:
global 变量名
变量名 = 值
# 声明一个全局变量a1
a1 = 100
def test1():
# 声明一个局部变量a1
# a1 = 200
# print(a1)
global a1
a1 = 200
print(a1)
# 在函数中声明全局变量b1
global b1
b1 = 300
- nonlocal关键字只能在函数中使用
当需要在局部的局部中修改局部变量的值,就使用nonlocal - 语法:
nonlocal 变量名
变量名 = 值
def func1():
# 声明一个局部变量a2
a2 = 'abc'
# python中函数可以声明函数
def func11():
nonlocal a2
a2 = 'python'
print('func11-a2:', a2)
# a3的作用域在func11中
a3 = 111
func11()
print('func1-a2:', a2)
# 思考?
funtions = []
for x in range(5):
def func1(a):
return a*x
funtions.append(func1)
t1 = funtions[0]
t2 = funtions[2]
print(t1(2))
print(t2(2))
二、函数作为变量
- python中,声明函数其实就是声明一个类型是function的变量,函数名就是变量名
函数名作为变量除了可以用来调用函数获取返回值
# 声明类型是int类型的变量a
a = 10
print(type(a))
# 声明类型是dict类型的变量b
b = {'a': 12, 'b': 200}
print(type(b))
print(b['a'])
# 声明类型是function类型的变量c
c = lambda x: x*x
print(type(c))
c(10)
# # 声明类型是function类型的变量d
def d(x):
def e():
print('abc')
e()
return x*x
print(type(d))
d(10)
# 1.让一个变量给另外一个变量赋值
# 声明一个列表变量list1
list1 = [1, 2, 3]
# 使用列表变量list1给list2赋值
list2 = list1
# 将list2当成列表来用
print(list2[0])
# 声明一个函数变量func11
def func11():
print('我是函数')
# 使用函数变量func11给ff赋值
ff = func11
# 将ff当成函数来用
ff()
# 2.将变量作为列表的元素或者字典的值
# 声明列表变量list1
list1 = [100, 200, 300]
# 将列表变量list1作为列表list2的元素
list2 = [list1, 100]
print(list2[0][0])
# 声明一个函数变量func2
def func2():
print('我是函数2')
# 将函数变量func2作为列表list2的元素
list2 = [func2, 100]
print(list2[0]())
- 将函数1作为实参,传递给函数2;这儿的函数2就是一个高阶函数(实参高阶函数)
def test(x):
# x = func3
print('test:', x)
if not isinstance(x, int):
x()
# 声明一个int类型的变量a
a = 10
# 将变量a作为test的实参
test(a)
# 声明一个fucntion类型的变量func3
def func3():
print('我是函数3')
test(func3)
- sort函数
def sort(self, key=None, reverse=False)
key - 确定排序的时候以什么值为标准来排序(默认以列表元素大小为标准排序)
需要传一个函数(函数需要一个参数和一个返回值,参数是指列表的一个元素)
reverse - 是否降序排序,需要一个bool值
o = lambda x: x[1]
print(max([("a", 100), ("b", 20), ("c", 10)], key=o))
三、迭代器
- 1.迭代器(iter)
迭代器是python中容器类的数据类型,可以同时存储多个数据
取迭代器中的数据只能一个一个取,取出来的数据就不存在了 - 2.迭代器中数据来源
a.将其他序列转换成迭代器
b.使用生成式、生成器去产生数据
所有序列都能转换成迭代器
# 将数据转化成迭代器
iter1 = iter("sdks")
print(iter1)
iter2 = iter([1, 25, 54])
print(iter2)
iter3 = iter({"name": "装甲师", "age": 500})
print(iter3)
>>>>
<str_iterator object at 0x000001B630C9F2E8>
<list_iterator object at 0x000001B630C9F320>
<dict_keyiterator object at 0x000001B630BA86D8>
- 2.获取迭代器中的元素
next(迭代器) - 取出迭代器中第一个元素(已经取出的元素,不能返回)
StopTteration
当迭代器是空的时候,使用next获取元素,会出现StopTteration异常
通过for循环取出迭代器中的每个元素
四、生成器 - 什么是生成器
生成器就是迭代器;迭代器不一定是生成器
调用带有yield关键字的函数,拿到的结果就是一个生成器。生成器中元素就是yield关键字后边的值
2.生成器怎么产生数据
只要函数中有yield关键字,调用函数不会再执行函数体获取返回值,而是创建一个生成器。
当获取生成器的元素的时候,才会执行函数的函数体,执行到yield语句为止,并且将yield后面的值作为结果返回;
并且保存当前执行的位置。
获取下一个元素的时候,就从上次结束的位置接着往下去执行函数,直到函数结束或者遇到yield为止;
如果遇到yield就将yield后面的值作为结果返回,并且保存当前执行的位置。如果函数结束了,就出现StopIteration异常
生成器对应的函数,执行完成遇到yield的次数,决定了生成器能产生的数据的个数
def creat_id():
num = 0
while True:
yield "stu" + str(num).zfill(3)
num += 1
gener_id = creat_id()
for _ in range(11):
print(next(gener_id))
>>>>
stu001
stu002
stu003
stu004
stu005
stu006
stu007
stu008
stu009
stu010
四、生成式
-
迭代器:容器,可以同时存储多个数据,取的时候只能一个一个取,
并且取出的不能返回
生成器:就是迭代器,数据是通过调用函数,获取yield后面的值而产生的
数据会在获取的时候产生
调用一个yield关键的函数,就是创建一个生产器 -
生成式
""" -
格式一:结果是一个生成器(迭代器)
(表达式 for 变量 in 序列) --> 展开:
def func():
for 变量 in 序列:
yeild 表达式
注意:表达式的结果就是每次循环生成器产生的数据 -
格式2:
(表达式 for 变量 in 序列 if 条件语句)
----> 展开:
def func1():
for 变量 in 序列:
if 条件语句:
yeild 表达式
gen1 = (10 for i in range(5))
print(gen1)
print(next(gen1))
gen2 = (i for i in range(5))
for _ in range(5):
print(next(gen2))
gen3 = (i for i in range(10) if i % 2)
for _ in range(5):
print(next(gen3))
list1 = list(i for i in range(10) if i % 2)
print(list1)
>>>>
<generator object <genexpr> at 0x00000263E742B830>
10
0
1
2
3
4
1
3
5
7
9
[1, 3, 5, 7, 9]
{1: 'a', 2: 'b', 3: 'c'}
五、模块
1.python 中一个文件就是一个模块
关联
- 方式一: import 模块名 - 将指定的模块导入当前模块中(模块名就是py文件的文件名)
说明:
a.执行import的时候,实质会进入指定的模块对应的py文件中,去执行里面的内容
b.import导入模块的时候,会检测当前模块之前是否已经导入过,如果已经导入就不在导入
c.通过import去导入一个模块后,可以通过 模块名.全局变量 去使用被导入模块中的内容
- 方式二:
from 模块名 import 变量名/函数名 - 导入模块中指定的变量和函数
说明:
a.执行到导入模块的语句的时候,还是会执行指定模块中的所有语句
b.通过from - import 导入的时候,导入多次还是只执行一次(查重)
c.使用的时候只能用import后面的变量/函数,而且用的时候不用在前面加模块名
d.import后面可以使用逗号将多个变量/函数隔开,也可以使用*号将模块中所有的全局变量一起导入
- 重新名
import 模块名 as 新模块名
form 模块名 import 变量名 as 新变量名
##### 2.补充
- 函数 - 对功能进行封装 - 获取当前时间对应的代码封装到函数中
模块 - 对多个功能和多个数据进行封装 - 将所有和xx相关的函数或变量放到一个py文件里
包 - 对多个模块进行封装 - 将所有和时间相关的朋友文件放到一个文件夹中
包:含有 __init__.py文件的文件夹
包的导入
import 包名 - 会直接执行摆钟的 __init__.py文件的内容
import 包名.模块名 - 导入包中指定的模块
from 包名 import 模块名
form 包名.模块名 import 变量
#### 六、选择性导入
- 在模块中将不需要其他其他模块导入和执行的代码写到if __name__ == '__main__':语句
这样就可以阻止代码被其他模块执行
原理:每个模块都有一个__name__属性,默认值是模块对应的py文件的名字
当正在直接执行模块的时候,模块的__name__属性值就会变成'__main__'
当import模块的时候,执行模块,模块的__name__属性不是'__main__'
if __name__ == '__main__':
# 写在这儿的代码不会被其他模块执行;声明的变量也不会被其他模块执行
print("我就在这儿,不走")
网友评论