栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python3 函数学习笔记03——函数进阶

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python3 函数学习笔记03——函数进阶

函数的作用域

作用域:变量的访问权限,全局变量所在的位置在全局作用域,局部变量所在的位置仅在局部作用域。
函数内部可以直接访问其外部的变量,但函数外部不能直接访问其内部的变量。如果函数外部需要访问函数内部的变量,需函数内部把相应的变量以return返回出来。

"""
全局作用域与局部作用域
"""
a = 10  # 全局变量 -> 全局作用域
print(a)

def func():   # 全局的一个函数
    b = 20   # 局部变量 -> 局部作用域
    print(a)
func()
print(b)	# 此时不能直接访问变量b

def func3():
    func()	# 访问全局函数
func3()
"""
函数外部需要访问函数内部的变量
"""
def func():
    c = 10
    return c

c1 = func()
print(c1)
函数的嵌套

函数相当于一个变量,可以作为返回值进行返回,也可以作为参数进行互相传递。
函数名实际上就是一个变量名, 都表示一个内存地址。

"""
函数可以被其它的函数调用
"""

def func1():
    pass

def func2():
    func1()  # 此时是函数的调用,并非函数嵌套

func2()
"""
函数的嵌套
"""
def func1():
    b = 20
    def func2():  # 函数的嵌套,相当于局部变量
        pass
    # func2 = def():
    print(b)
    func2()  # 局部变量一般都是在局部作用域中被访问
print(func1())
"""
嵌套函数的运行顺序
"""
def func1():
    print(123)			# (1)
    def func2():
        print(456)		# (3)
        def func3():
            print(789)	# (5)
        print(1)		# (4)
        func3()
        print(2)		# (6)
    print(3)			# (2)
    func2()
    print(4)			# (7)

func1()

""" 运行结果
123
3
456
1
789
2
4
"""
"""
函数可以作为返回值进行返回,也可以作为参数进行互相传递
"""
def func():
    def inner():
        print(123)
    print(inner)
    return inner  # 返回的是函数名称, 此时是把一个函数当成一个变量进行返回的
    
b1 = func()		# b1是func的内部inner
print(b1)
b1()

def an():
    print(123)
an()
bn = an		# 作为参数进行传递
bn()
"""
代理模式
"""
def func(an):  # 此时an收到的是一个函数
    an()  # 执行这个函数

def target():
    print("我是target")
    
func(target)  # 实参可以是函数
两个关键字:global与nonlocal
a = 10
def func():
    print(a)
    # 要在函数内部修改全局的变量a
    global a	# 用关键字“global”把外面的全局变量引入到局部
    a = 20		# 此处可修改全局变量a
func()
print(a)
def func():
    a = 10
    def func2():
        nonlocal a  # 向外找一层,如果有对应的变量就引入, 没有就继续向外一层, 直到全局(不包括)
        a = 20		# 此处可修改外层局部变量a
    func2()
    print(a)
func()
闭包函数

闭包函数的本质:内层函数对外层函数的局部变量的使用
闭包函数的作用:
1. 可以让一个变量常驻于内存
2. 可以避免一个变量像全局变量那样被轻易修改
3. 多了一种传参的方式

def func():
    a = 10
    def inner():
        nonlocal a
        a += 1
        return a
    return inner	# 函数对象可以被赋值、当做参数、当做容器类型的元素,也可以作返回值

ret = func()	# ret就是函数名inner
r1 = ret()		# 运行inner函数,获取闭包函数的返回值
print(r1)

两种为函数体传参的方式:

# 方式一:直接把函数体需要的参数定义成形参
def f2(x):
    print(x)
f2(1)

# 方式二:以闭包函数的方式传参
def f1(x): # x=3
    def f2():
        print(x)
    return f2

x=f1(3)		# 传参
print(x)	# f2函数的内存地址
x()			# 执行f2函数

两种为函数体传参方式的应用:

import requests

# 传参方式一:
def get(url):
    response = requests.get(url)
    print(len(response.text), url)

get('https://www.baidu.com/')
get('https://www.csdn.net/')
get('https://www.bilibili.com/')


# 传参方式二:
def outter(url):
    def get():
        response = requests.get(url)
        print(len(response.text), url)
    return get

baidu = outter('https://www.baidu.com/')
baidu()

csdn = outter('https://www.csdn.net/')
csdn()

bilibili = outter('https://www.bilibili.com/')
bilibili()
装饰器

装饰器就是一个函数,在不改变原函数的代码以及调用方式的前提下,为原函数增加新的功能,其本质是闭包。

标准装饰器

# 定义装饰器
def wrapper(fn):
	def inner(*args, **kwargs):
#         '''添加额外的功能:执行被装饰函数之前的操作'''
		ret = fn(*args, **kwargs)
#         '''添加额外的功能:执行被装饰函数之后的操作'''
		return ret
	return inner

# 使用装饰器
@wrapper
def func():
	pass

多个装饰器的运行顺序——远先近后,先进后出

def wrapper01(fn):
    def inner(*args, **kwargs):
        print("wrapper01入口")
        ret = fn(*args, **kwargs)
        print('wrapper01出口')
        return ret
    return inner

def wrapper02(fn):
    def inner(*args, **kwargs):
        print('wrapper02入口')
        ret = fn(*args, **kwargs)
        print('wrapper02出口')
        return ret
    return inner

@wrapper01
@wrapper02
def main():
    print('main函数')

main()

运行结果:

wrapper01入口
wrapper02入口
main函数
wrapper02出口
wrapper01出口

有参装饰器

# 有参装饰器模板
def outter(x,y,z):
    def wrapper(fn):
        def inner(*args, **kwargs):
            res = fn(*args, **kwargs)
            return res
        return inner
    return wrapper

@outter(1,y=2,z=3)
def func():
    pass
迭代器

迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果而继续的,并非单纯的重复。
可迭代对象与迭代器对象
1、可迭代对象(可以转换成迭代器的对象):内置有方法__iter__()对象

可迭代对象.iter(): 得到迭代器对象

2、迭代器对象:内置有方法__next__()和方法__iter__()的对象

迭代器对象.next():得到迭代器的下一个值
迭代器对象.iter():得到迭代器的本身,调了与没调都是一样的

可迭代对象:字符串、列表、元组、字典、集合、文件对象
迭代器对象:文件对象

lst = ['Java', 'Python', 'C/C++', 'PHP']

# 获取迭代器对象
iterator = iter(lst)			# 方式一
iterator = lst.__iter__()		# 方式二

# 从迭代器中取值
#	一次取一项值,取值完成后再进行取值则抛出异常StopIteration
print(next(iterator))			# 方式一
print(iterator.__next__())		# 方式二

迭代器实现for循环:

lst = ['Java', 'Python', 'C/C++', 'PHP']

# for循环遍历列表
for item in lst:
	print(item)

# 迭代器遍历列表
iterator = iter(lst)
while True:
    try:
		print(next(iterator))
	except StopIteration:
		break
# 等价于
iter_ = lst.__iter__()
while True:
    try:
        print(iter_.__next__())
    except StopIteration:
        break

迭代器优缺点
1、优点:
I、为序列和非序列类型提供了一种统一的迭代取值方式。
II、惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用方法next()来计算出一个值,就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。
2、缺点:
I、除非取尽,否则无法获取迭代器的长度
II、只能取下一个值,不能回到开始,更像是‘一次性的’,迭代器产生后的唯一目标就是重复执行方法next()直到值取尽,否则就会停留在某个位置,等待下一次调用方法next();若是要再次迭代同个对象,只能重新调用方法iter()去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值。

生成器

在函数内一旦存在yield关键字,调用函数并不会执行函数体代码,而会返回一个生成器对象,生成器即自定义的迭代器。
生成器对象调用方法__next__()时会触发函数体代码的运行,然后遇到yield停下来,并将yield后的值当做本次调用的结果返回。
关键字yield可以用于返回值,但不同于return,函数一旦遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值。

def my_range(start,stop,step=1):
    # print('start...')
    while start < stop:
        yield start
        start+=step

g=my_range(1,5,2) # 1 3
print(next(g))
print(next(g))
print(next(g))

for n in my_range(1,7,2):
    print(n)
推导式
# 列表推导式
lst = [x for x in range(10) if x % 2 == 1]
print(lst)			# [1, 3, 5, 7, 9]

# 字典推导式
lst = ['Java', 'Python', 'C/C++', 'PHP']
dic = {i: lst[i] for i in range(len(lst))}
print(dic)			# {0: 'Java', 1: 'Python', 2: 'C/C++', 3: 'PHP'}

# 生成器表达式
iter_ = (x for x in range(1, 10, 3))
print(iter_)		# 生成器对象
print(iter_.__next__())
print(iter_.__next__())
print(iter_.__next__())
匿名函数
func = lambda x, y: x + y
# 等价于
def func(x, y):
	return x + y
print(func(2, 3))

func = lambda x, y: x if x > y else y
# 等价于
def func(x, y):
	if x > y:
		return x
	return y
print(func(2, 3))
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/977394.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号