一、函数的特殊用法
- 变量可以指向函数
- 函数名是一个变量
- 函数可以作为参数
# 函数的特殊用法
# 1. 函数名, 也是指向函数的变量
def my_abs(n):
if n < 0:
return -n
return n
print(my_abs(-1))
f = my_abs # 函数名就是变量,可以赋值
print(f(-2))
# 2. 函数可以当成参数
def fn(x, f):
x = 10+x
return f(x,20)
def f1(x,y):
return x*y
s = fn(1,f1)
print(s)
二、函数的作用域和嵌套
2.1函数的作用域
作用域: 变量起作用的范围(区域)
局部变量: 函数内部的变量
特点: 1 内存会被自动释放(调用后会自动回收内存,退出函数就不可以使用
全局变量: 整个文件都可以使用的变量
特点:1. 内存不会释放(消耗内存,但是可以一直使用)2. 容易被污染(可能被其他地方修改)
函数: 有作用域
内建函数作用域: B Built-in 作用所有python文件
python中提供的内置函数、内置变量
全局作用域: G Global
函数作用域: E Encoding
局部作用域: L local
# 内建作用域: B Built-in
# python中提供的内置函数,内置变量,内置函数
c = 1 # 全局作用域: G Global
def f1():
d = 2 # 函数作用域: E Enclosing
def f2():
e = 3 # 局部作用域:L Local
print()
# global
k = 10
def f3():
# 声明使用的是全局变量k,一般用于修改全局变量
global k
k = k + 20 # 修改全局变量
print("k=",k)
f3()
print(k)
print()
# nonlocal 关键字
p = 1
def f4():
p = 2
def f5():
# global p # 使用全局变量p=1
nonlocal p
p += 3
print("p=",p)
f5()
f4()
print(p)
2.2函数的嵌套
# 闭包:
# 外部函数 嵌套 内部函数,且返回内部函数,则外部函数的参数或变量捕获被释放
# 局部变量:
# 1. 变量的内存会被回收
# 2. 不会被污染(不会被函数外部修改)
# 全局变量
# 1. 变量不会被回收
# 2. 可能会被污染(可能被修改)
# 闭包:
# 1. 变量不会被回收
# 2. 变量不会被污染
无参嵌套
# 函数嵌套
def f1():
print('f1')
def f2():
print('f2')
return f2
f = f1() # f = f2
f()
print(f)
f1()() # 跟上面等价
带参函数嵌套
# 带参数的函数嵌套
def f3(x):
print('f3')
def f4(y):
print('f4', x, y)
return f4
f3(11)(22)
三、列表生成器和生成器
3.1 列表生成式
list comprehension
系统内置的用于创建list的方式
range(start,end,step)缺点:生成的列表一般情况下都是等差数列
代码演示:
# 生成列表
l = [1,2,3,4,5]
l = list(range(1,6))
l = []
for i in range(1,6):
l.append(i)
# 列表生成式/列表推导式
l = [i for i in range(1,6)] # [1, 2, 3, 4, 5]
l = [i*i for i in range(1,6)] # [1, 4, 9, 16, 25]
l = [i for i in range(1, 6) if i%2] # [1, 3, 5]
l = [i for i in range(1, 6) if i%2 and i > 2] # [3, 5]
l = [i for i in range(1, 6) if i%2 if i < 5] # [1, 3]
l = [i+j for i in "123" for j in "abc"]
# ['1a', '1b', '1c', '2a', '2b', '2c', '3a', '3b', '3c']
# 字典生成式
d = {i:i+1 for i in range(5)}
print(d) # {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}
# 集合生成式: 了解
s = {i*i for i in range(5)}
print(s) # {0, 1, 4, 9, 16}
3.2 生成器
# 生成器:generator
# 一般用于超多的数或无穷无尽
g = (i for i in range(1,6))
# print(g) # 生成器对象
# <generator object <genexpr> at 0x000001770D232F48>
# 需要使用next()来调用生成器
print(next(g))
# 使用forint来调用生成器,不会报错
for i in g:
print('i = ',i)
# 生成器函数: 有yield 关键字的函数
# yield:
# 1. 写在函数中,会让函数变成生成器函数
# 2. 每次使用next调用,会在yield暂停
# 3. 类似return, 可以返回值,但是不会结束函数
def fg():
print("111")
yield 100 #
print("222")
yield 200
print("333")
四、迭代器
4.1 可迭代对象
可迭代对象【实体】:可以直接作用于for循环的实体【Iterable】
可以直接作用于for循环的数据类型:
a.list,tuple,dict,set,string
b.generator【() 和yield】
isinstance:判断一个实体是否是可迭代的对象
代码演示:
#一、可迭代对象 #1.导入 from collections import Iterable #2.使用isinstance(数据,Iterable) print(isinstance([],Iterable)) print(isinstance((),Iterable)) print(isinstance({},Iterable)) print(isinstance((x for x in range(10)),Iterable)) print(isinstance("hello",Iterable)) print(isinstance(10,Iterable)) #False print(isinstance(True,Iterable)) #False print("****88")
4.2 迭代器
不但可以作用于for循环,还可以被next函数遍历【不断调用并返回一个元素,直到最后一个元素被遍历完成,则出现StopIteration】
目前为止,只有生成器才是迭代器【Iterator】
结论:迭代器肯定是可迭代对象,但是,可迭代对象不一定是迭代器
isinstance:判断一个实体是否是迭代器
代码演示:
#二、迭代器 from collections import Iterator print(isinstance([],Iterator)) print(isinstance((),Iterator)) print(isinstance({},Iterator)) print(isinstance("hello",Iterator)) print(isinstance((x for x in range(10)),Iterator)) #True print("****88")
4.3 可迭代对象和迭代器之间的转换
可以将可迭代对象转换为迭代器:iter()
代码演示:
#三、虽然list、tuple、dict、set、string都不是迭代器 #iter():将list、tuple、dict、set、string的 Iterable转换为Iterator print(isinstance(iter([]),Iterator)) print(isinstance(iter(()),Iterator)) print(isinstance(iter({}),Iterator)) print(isinstance(iter("hello"),Iterator))
总结:
a.凡是可以作用于for循环的对象都是Iterable类型
b.凡是可以作用于next函数的对象都是Iterator类型
c.list/tuple/dict/set/string都不是Iterator,可以通过iter()获得一个Iterator对象
【面试题】
区分可迭代对象和迭代器
五、偏函数
# 偏函数: 了解
print(int('1010')) # 10
print(int('1010', base=2))
print(int("1010", base=8)) # 2568
import functools
int2 = functools.partial(int, base=2)
print(int2("1010"))
# 转成十六进制
print(hex(10)) # 0x a
# 转成八进制 0o 开头
print(oct(10))
# 转成二进制 0b 开头
print(bin(10))
print("*"*100)
十六进制=0xa
print(十六进制)
八进制=0o12
print(八进制)
二进制=0b1010
print(二进制)