Python Day 09 函数的特殊用法 知识点总结

一 变量可以指向函数

  1. 打个比方 abs() 是系统内置的函数之一 绝对值
    print(abs(-10)) #10
    print(abs) #
  1. abs(-10) 是函数的调用 而abs是函数本身
  2. 函数本身也可以直接赋值给一个变量 也就是说 变量可以指向一个函数 如 f=abs 那么f也会赋予绝对值的意义
  3. f = abs 表示f已经指向了abs所在的函数 所以调用abs和调用f是一个道理 都是可以实现绝对值的效果
  1. 函数名是一个变量
  1. 函数名也是可以成为一个变量的代名词 比如说 abs = 1 那么之后的abs将不再是一个函数 也没有一个函数的功能
  1. 函数作为一个参数
    变量可以指向函数 函数名是一个变量 而函数的形参本身就是一个变量 可以接受实参 那么一个函数就可以接受另外一个函数作为参数
    如:
    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
  1. 注意 内函数中可以直接使用外函数的临时变量

四 变量的作用域

  1. 出现的原因
  1. 变量的作用域 变量可以被使用 被访问的范围
  2. 程序中的变量并不是在任意的语句中都可以被访问 访问权限取决于这个变量被定义在那个位置
  1. 作用范围划分
  1. 局部作用域 L — Local
  2. 函数作用域 E — Enclosing 将变量定义在闭包外的函数中
  3. 全局作用域 G — Global
  4. 内建作用域 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()
  1. 变量的查找规则
    查找的顺序为 L>E>G>B [极端情况:当所有的变量都同名的情况之下]
  1. 结论一 : 在函数中定义的变量[形参,在函数体中定义的变量],作用域仅在函数内部 变量的生命周期随着函数的出现而出现 函数执行完毕后则变量随着被销毁
  2. 结论二 :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()
  1. 全局变量和局部变量[掌握]
    全局变量: 将变量定义在函数的外面
    局部变量: 将变量定义在函数的内部
    注意: 局部变量只能在其被声明的当前函数中使用 而全局变量可以在整个程序中使用
#全局变量
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)
  1. global 和 nonlocal 关键字的使用[掌握]
    使用场景 当内部作用域[局部作用域,函数作用域] 想要修改全局变量的作用域时
  1. global
#global

#全局变量
num = 1
def fun1():
 #此时要使用全局变量中的num,需要给编译器做一个声明,
 #声明此处使用num就是使用的全局变量中的num
	global num
	print(num)
  1. 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
"""

五 列表生成式和生成器[掌握]

  1. 说实话 这就是简化了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']
  1. 生成器
#生成器

#方式一:(),将列表生成式中的[]改成()
#列表生成式的类型是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
'''

六 迭代器

  1. 可迭代对象
    可迭代对象[实体] : 可以直接作用for循环的实体[lterable]
    可以直接作用于for循环的数据类型:
    a. list tuple dict set string
    b. generator [()和 yield]
    isinstance( , Interable) : 判断一个实体是否为可迭代对象
  2. 迭代器
    不但可以作用于for循环 还可以被next函数遍历[不断调用并返回一个元素 直到最后一个元素被遍历完成 则出现StopIteration]
    目前为止 只有生成器才是迭代器[Iterator]
    结论:迭代器肯定是可迭代对象 但是 可迭代对象不一定是迭代器
    isinstance( , Iterator) : 判断一个实体是否为迭代器
  3. 可迭代对象和地带其之间的转化
    可以将迭代对象转换为迭代器: 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对象