函数进阶

命名空间和作用域

命名空间

命名空间 有三种
内置命名空间 —— python解释器
  就是python解释器一启动就可以使用的名字存储在内置命名空间中
  内置的名字在启动解释器的时候被加载进内存里
全局命名空间 —— 我们写的代码但不是函数中的代码
  是在程序从上到下被执行的过程中依次加载进内存的
  放置了我们设置的所有变量名和函数名
局部命名空间 —— 函数
  就是函数内部定义的名字
  当调用函数时 才会产生这个名称空间 随着函数执行的结束 这个命名空间随之消失

在局部:可以使用全局、内置命名空间中的名字
在全局:可以使用内置命名空间中的名字,但是不能用局部中使用
在内置:不能使用局部和全局的名字的

如下面的例子

#局部命名空间的名字 不可以在全局空间中被调用
def func():
a = 1
func()
print(a) #报错——NameError: name 'a' is not defined

命名空间的使用原则:

  1、在正常情况下,直接使用内置的名字
  2、当我们在全局定义了和内置命名空间中同名的名字时,会使用全局的名字
  3、在嵌套中,当自己的这一级中有所需的名字时,就不去找上一级找了
  4、在嵌套中,如果自己没有 就找上一级要 上一级没有再找上一级 如果内置的名字空间也没有 就报错
  5、多个函数应该拥有多个独立的局部名字空间,不互相共享

作用域

作用域 有两种
  全局作用域 —— 作用在全局 —— 内置和全局命名空间中的名字都属于全局作用域 —— globals()
  局部作用域 —— 作用在局部 —— 函数(局部命名空间中的名字属于局部作用域) —— locals()

我们接着来看下面  global 的例子

#global 声明过得变量,让在函数外部的 print() 可以进行打印
a = 1
def func():
global a #使用 global 进行声明
a = 2
func()
print(a) #输出结果为 2 b=1
def func():
#global b
b = 2
func()
print(b) #此时结果还是 1,因为在内部的任何操作 不影响外部的

对于不可变数据类型 在局部可以查看全局作用域中的变量,但是不能直接修改
如果想要修改,需要在程序的一开始添加 global 声明
如果在一个局部(函数)内声明了一个 global 变量,那么这个变量在局部的所有操作将对全局的变量有效

接着我们对比着 global() 变量来看 locals() 变量

#可以看出两个打印的内容一个为局部一个为全局
a = 1
b = 2
def func():
x = 'aaa'
y = 'bbb'
print(locals()) #输出局部的变量,根据 locals 所在的位置
print(globals()) #永远打印全局的名字,可以看到打印出了好多内容 func()

你一定会觉得 globals 函数在很多时候很好用(我也是这么觉得着)
可以 globals 这个函数涉及到代码的安全性 不推荐使用
可以通过传参和接收返回值 来完成原本使用 global 完成的事情

#通过传参和接收返回值来时实现调用全局变量
a = 1
def func():
global a
a = 3 func()
print(a) #改为: a = 2
def func(a):
a += 1
return a print(func(a)) #此时返回 3

函数的嵌套与调用

#求两个数字的最大值
def max(a,b):
return a if a > b else b
print(max(15,98))

#求三个数的最大值
def the_max(a,b,c):
e = max(a,b) #把其中的两个值 丢给 max 去解决了
return max(e,c)
print(the_max(56,85,65))

不能直接调用函数内层的函数名

def outer():
def inner():
print('inner') #outer() #没有结果
#inner() #报错
#outer(inner()) #报错

可以使用 nonlocal 实现函数嵌套调用

# nonlocal
# 对全局无效
# 对局部 也只是对 最近的 一层 有影响
def outer():
a = 1
def inner():
b = 2
print(a) #内部函数可以使用外部函数的变量
print('inner')
def inner2():
print(a,b)
print('inner2')
nonlocal a #声明了上面第一次出现 a 局部变量,没找到 则报错(不常用)
#global #在此处使用不能达到要求,因为此时 a = 1 为局部变量
a += 1 #在这里操作是想修改上面 a = 1 的这个值(不可变数据类型的修改)
inner2() #函数必须是先定义后调用
print('局部变量 a:',a)
inner()
outer() #输出结果
'''
1
inner
1 2
inner2
局部变量 a: 2 #这里可以看到外部函数的变量在内部函数中被修改了
'''

函数的赋值

函数名可以用于:赋值、容器类型的元素、返回值、参数

#函数名的赋值与作为容器类型的元素使用
def func():
print(123) #func()    #函数名就是内存地址
func2 = func #函数名可以用于赋值
func2()    #所以结果为 123 l = [func,func2] #函数名可以作为容器类型的元素 如下面 for 循环
print(l) #可以看出赋值后的内存地址是一致的
for i in l:
i()
#函数名作为返回值与参数
def func():
print(123) def func2(f):
f()
return f #函数名可以作为函数的返回值
func2(func) #函数名可以作为函数的参数
func3 = func2(func) #用于接收返回值
func3()

闭包

定义:

必须符合:是嵌套函数,且内部函数调用外部函数的变量

def outer():
a = 1
def inner():
print(a) #到这里就是一个闭包了
print(inner.__closure__) #可以使用 __closure__ 来检测是否是闭包
#返回 (<cell at : int object at ,) 这些就表示是一个闭包了
inner()
outer()

闭包常用形式:接收返回值

在一个函数的内部去使用它外部的变量

#不过下面并不是闭包常用的形式
def outer():
a = 1
def inner():
print(a)
inner()
outer() #而下面的才是(采用接收返回值的形式)
def outer():
a = 1
def inner():
print(a)
return inner
inn = outer()
inn()
#在这里 a = 1 不会因为 outer() 函数的结束而消失,因为 inn() 后面可能会用到,所以才不会消失
#使用闭包的好处在于 我保护了 a = 1 这个变量,它既不是全局变量,我又可以在使用它时,去使用它
#延长了 a = 1 的声命周期 节省了创建和删除变量 a = 1 的时间

闭包的应用

##获取网站信息
#现在已经可以拿到网页了,但是我们一般都要把它封装成一个函数
from urllib.request import urlopen
ret = urlopen('https://fanyi.baidu.com/translate#en/zh/inter').read()print(ret)
print(ret) #我们使用闭包来封装它
from urllib.request import urlopen
def get_url():
url = 'https://fanyi.baidu.com/translate#en/zh/inter'
def inner():
ret = urlopen(url).read()
print(ret)
return inner
get_func = get_url()
get_func()
#这样的好处在于 就算在外部调用了 n 次 get_func() 而创建 n 次 url 这个变量

day 10 - 1 函数进阶的更多相关文章

  1. python学习笔记:第10天 函数进阶和作用域

    目录 1. 函数进阶 2. 命名空间 3. 关键字global和nonlocal 1. 函数进阶 动态接收位置参数 之前写的函数都是固定参数的,假设有个函数需要的参数由几十个,一个个写在形参的位置会非 ...

  2. 巨蟒python全栈开发-第10天 函数进阶

    一.今日主要内容总览(重点) 1.动态传参(重点) *,** *: 形参:聚合 位置参数*=>元组 关键字**=>字典 实参:打散 列表,字符串,元组=>* 字典=>** 形参 ...

  3. Python【day 10】函数进阶-小结

    本节主要内容1.动态参数 *args **kwargs 形参:*args将多个位置参数聚合打包成元组 **kwargs将多个关键字参数聚合打包成字典 实参:*li1将列表进行解包打散成多个位置参数 * ...

  4. Python【day 10】函数进阶-动态函数

    形参小结 1.位置参数2.默认值参数3.动态参数 1.*args 位置参数的动态传参. 系统会自动的把所有的位置参数聚合成元组 2.**kwargs 关键字参数的动态传参. 系统会自动的把所有的关键字 ...

  5. 10.Python初窥门径(函数进阶)

    Python(函数进阶) 一.函数的传参(接上期) 形参角度(一共四种,后两种) 动态参数(万能参数)* # 定义一个函数时,*所有的位置参数聚合到一个元组中 def func(*args): # * ...

  6. python基础 (初识函数&函数进阶)

    函数基础部分 .什么是函数? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率. 2.定义函数 定义:def 关键词开头,空格之后接函数名 ...

  7. python基础之 初识函数&函数进阶

    函数基础部分 1.什么是函数? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率. 2.定义函数 定义:def 关键词开头,空格之后接函数名 ...

  8. python函数进阶(函数参数、返回值、递归函数)

    函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形 ...

  9. python大法好——递归、内置函数、函数进阶

    1.递归(自己干自己) def fun(n): n=n/2 print(n) if(n>2) fun(n) #函数调用 fun(10) 结果是5 2 1 0 递归的执行过程:递归执行到最里面一层 ...

随机推荐

  1. vue层级关系的数据管理

    项目背景:为一些有层级关系的数据管理做一套后台管理系统,例如一个小区,里面是有许多楼,楼里有许多层,每一层有许多不同的房······,现在就是要实现对这些数据进行增删改查操作. 1.Tree(树形组件 ...

  2. 牛客网暑期ACM多校训练营 第九场

    HPrefix Sum study from : https://blog.csdn.net/mitsuha_/article/details/81774727 k较小.分离x和k. 另外的可能:求a ...

  3. Springboot+WebSocket+Kafka(写着玩的)

    闹着玩的来源:前台发送消息,后台接受处理发给kafka,kafka消费者接到消息传给前台显示.联想到websocket. 最终效果如图: 页面解释: 不填写内容的话,表单值默认为Topic.Greet ...

  4. ES6学习:Map结构的目的和基本用法

    Map结构的目的和基本用法 JavaScript的对象(Object)本质上是键值对的集合(Hash结构),但是只能用字符串作为键.这给它的使用带来了很大的限制.   1 2 3 4 5 6 7 8 ...

  5. log4net 开启内部调试

    大家都在用LOG4NET,但这是封装好的,在有时我们找不到原因时会想到是不是发生在里面,比如,配置好了日志记录到数据库(Mysql.Oracle.Sql Server)等,但就是记录不上,又找不到原因 ...

  6. 完美解决windows+ngnix+phpcgi自动退出的问题

    [摘要]在windows下搭建nginx+php环境时,php-cgi.exe会经常性的自动关闭退出,本文介绍通过使用xxfpm进程管理器管理php-cgi.exe. php-cgi.exe在wind ...

  7. scrapy中css选择器初识

    由于最近做图片爬取项目,涉及到网页中图片信息的选择,所以边做边学了点皮毛,有自己的心得 百度图库是ajax加载的,所以解析json数据即可 hjsons = json.loads(response.b ...

  8. Mac 上有哪些值得推荐的软件?冷门小众软件但实用

    确实Mac上有很多小众.冷门,但却是十分实用.值得推荐的工具,小编针对用的比较多的软件,整理了一些,希望有帮助. The Unarchive:解压缩工具 macOS 对于压缩文件的处理不是很好.如果你 ...

  9. JavaSE_List&Array_Java1.7

    这里简单写了下List和Array的相互转换 package cn.rocker.collection.list; import org.junit.Test; import java.util.Ar ...

  10. 《玩转Django2.0》读书笔记-探究视图

    <玩转Django2.0>读书笔记-探究视图 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 视图(View)是Django的MTV架构模式的V部分,主要负责处理用户请求 ...