Python Day 09 函数的特殊用法 知识点总结
一 变量可以指向函数
- 打个比方 abs() 是系统内置的函数之一 绝对值
print(abs(-10)) #10
print(abs) #
- abs(-10) 是函数的调用 而abs是函数本身
- 函数本身也可以直接赋值给一个变量 也就是说 变量可以指向一个函数 如 f=abs 那么f也会赋予绝对值的意义
- f = abs 表示f已经指向了abs所在的函数 所以调用abs和调用f是一个道理 都是可以实现绝对值的效果
- 函数名是一个变量
- 函数名也是可以成为一个变量的代名词 比如说 abs = 1 那么之后的abs将不再是一个函数 也没有一个函数的功能
- 函数作为一个参数
变量可以指向函数 函数名是一个变量 而函数的形参本身就是一个变量 可以接受实参 那么一个函数就可以接受另外一个函数作为参数
如:
def add(x,y,abs):
return abs(x) + abs(y)
二 偏导数 [了解]
主要是针对系统函数 如果系统函数无法满足需求 则可以在这个系统函数的基础上生成一个新的函数–偏导数 两个函数可以实现不一样的功能
import functools
print(int('123',base = 8)) #这个的意思是 前面的数字是一个八进制数字 print的内容为 转化为十进制输出
print(int('123',base =16)) #前面的数字是十六进制数字 print十进制输出
#由于转化大量二进制 每次传入base = 2 很麻烦 所以我们可以把这个功能提取出来
def customInt(x,base = 2):
return int(x,base = 2)
print(customInt('110'))
print(customInt('11010110'))
三 闭包[掌握]
如果在一个函数的内部定义另外一个函数 那么外部的函数叫做外函数 里面的函数叫做内函数
如果在外部函数中定义一个内部函数 并且外部函数的返回值为内部函数 就构成了一个闭包 则这个内部函数称为闭包 [closure]
#最简单的闭包
def func(str):
def innerFunc():
print('Hello')
return innerFuc
- 注意 内函数中可以直接使用外函数的临时变量
四 变量的作用域
- 出现的原因
- 变量的作用域 变量可以被使用 被访问的范围
- 程序中的变量并不是在任意的语句中都可以被访问 访问权限取决于这个变量被定义在那个位置
- 作用范围划分
- 局部作用域 L — Local
- 函数作用域 E — Enclosing 将变量定义在闭包外的函数中
- 全局作用域 G — Global
- 内建作用域 B — Built-in
num4 = int(2.9) #B 内建作用域
num3 = 3 #G 全局作用域
def outer():
num1 = 1 #E 函数作用域
def inner():
num2 = 2 #L 局部作用域
print(num1,num2,num3,num4)
return inner
f = outer()
f()
- 变量的查找规则
查找的顺序为 L>E>G>B [极端情况:当所有的变量都同名的情况之下]
- 结论一 : 在函数中定义的变量[形参,在函数体中定义的变量],作用域仅在函数内部 变量的生命周期随着函数的出现而出现 函数执行完毕后则变量随着被销毁
- 结论二 :python中只有模块[module]、类[class] 和函数[def,lambda]才会引入新的作用域 其他的代码块 if while for try-except 语句都不会引入新的作用域
x = 0
x = int(3.3)
def outer1():
x = 1
def inner1():
x = 2
#【就近原则】
print(x) #取得就是2 接下来是 1 再接下来是3 在接下来是0
return inner1
f1 = outer1()
f1()
- 全局变量和局部变量[掌握]
全局变量: 将变量定义在函数的外面
局部变量: 将变量定义在函数的内部
注意: 局部变量只能在其被声明的当前函数中使用 而全局变量可以在整个程序中使用
#全局变量
total = 0
def show():
print(total)
show()
if True:
total = 20
print(total)
total = 10
print(total)
def add(arg1,arg2):
#arg1,arg2,total1都属于局部变量
total1 = arg1 + arg2
print(total1)
add(10,20)
#print(total1)
- global 和 nonlocal 关键字的使用[掌握]
使用场景 当内部作用域[局部作用域,函数作用域] 想要修改全局变量的作用域时
- global
#global
#全局变量
num = 1
def fun1():
#此时要使用全局变量中的num,需要给编译器做一个声明,
#声明此处使用num就是使用的全局变量中的num
global num
print(num)
- nonlocal
#前提:nonlocal关键字是定义在闭包中
x = 0
def outer():
x = 1
def inner():
#使用nonlocal关键字进行声明,相当于将局部作用域范围扩大了
nonlocal x
x = 2
print("inner:",x)
#return inner
inner()
print("outer:",x) #2
outer()
print("global:",x)
"""
原本:
inner: 2
outer: 1
global: 0
"""
"""
修改:
inner: 2
outer: 2
global: 0
"""
五 列表生成式和生成器[掌握]
- 说实话 这就是简化了for-in 循环 变成了一行内解决而已
#1
#使用列表生成式完成上面的需求
#列表生成式的格式:[生成的元素 for-in循环]
list3 = [x ** 2 for x in range(1,11)]
print(list3) #[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
#2.
#[4,16,36,64,100]
list4 = [x ** 2 for x in range(1,11) if x % 2 == 0]
print(list4)
#3.嵌套for循环,第一个循环就相当于外层循环,第二个循环就相当于内层循环
list5 = [m + n for m in "ABC" for n in "XYZ"]
print(list5)
#["AX","AY","AZ"....]
"""
for m in "ABC":
for n in "XYZ":
print(m + n)
"""
#4
#for k,v in dict.items)():
d = {"x":"1","y":"2","z":"3"}
for k,v in d.items():
print(k,v)
list6 = [k + "=" + v for k,v in d.items()]
print(list6) #['x=1', 'y=2', 'z=3']
- 生成器
#生成器
#方式一:(),将列表生成式中的[]改成()
#列表生成式的类型是list,生成器的类型是generator【当做一种新的数据类型】
r1 = (x ** 2 for x in range(1,6))
print(r1) #(1,4,9,16,25)
print(type(r1)) #<class 'generator'>
"""
for i in r1:
print(i)
"""
#生成器区别于列表生成式:可以使用next遍历,每调用一次则获取一个元素
#next()
print(next(r1))
print(next(r1))
print(next(r1))
print(next(r1))
print(next(r1))
#注意:当生成器中的元素全部获取完成之后,接着调用next函数的,则会出现StopIteration
#print(next(r1)) #StopIteration异常
#方式二:yield---->让步
#(x for x in range(1,6))----->1,2,3,4,5
def test(n):
for i in range(1, n + 1):
#执行到yield的时候,则函数会停止,将yiled后面的变量返回
yield i ** 2
#yield后面的代码的执行时机:当调用next函数的时候
print(i)
t = test(5)
print(t) #<generator object test at 0x0000019CC432A1A8>
print(next(t))
print(next(t))
print(next(t))
print(next(t))
print(next(t))
#'''
1
1
4
2
9
3
16
4
25
'''
六 迭代器
- 可迭代对象
可迭代对象[实体] : 可以直接作用for循环的实体[lterable]
可以直接作用于for循环的数据类型:
a. list tuple dict set string
b. generator [()和 yield]
isinstance( , Interable) : 判断一个实体是否为可迭代对象 - 迭代器
不但可以作用于for循环 还可以被next函数遍历[不断调用并返回一个元素 直到最后一个元素被遍历完成 则出现StopIteration]
目前为止 只有生成器才是迭代器[Iterator]
结论:迭代器肯定是可迭代对象 但是 可迭代对象不一定是迭代器
isinstance( , Iterator) : 判断一个实体是否为迭代器 - 可迭代对象和地带其之间的转化
可以将迭代对象转换为迭代器: iter()
#一、可迭代对象
#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")
#二、迭代器
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")
#三、虽然list、tuple、dict、set、string都不是迭代器#iter():将list、tuple、dict、set、string的 Iterable转换为Iteratorprint(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对象