函数进阶

1、函数命名空间和作用域

命名空间一共分为三种:

  全局命名空间

  局部命名空间

  内置命名空间

*内置命名空间中存放了python解释器为我们提供的名字:input , print , str , list , tuple...

三种命名空间之间的加载与取值顺序:

加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

取值顺序:

  在局部调用:局部命名空间->全局命名空间->内置命名空间

  在全局调用:全局命名空间->内置命名空间

综上所述,在找寻变量时,从小范围,一层一层到大范围去找寻。

作用域

作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

局部作用域:局部名称空间,只能在局部范围生效

globals和locals方法:

global 关键字:

  1、声明全局变量;

  2、在局部作用域对全局作用域的全局变量进行修改,只适用于字符串和数字

## 变量为字符串或数字,需要global声明变量
b = 1
def func():
global b ## 将局部变量 b 申明成全局变量
b = 13
return b print(func())

运行结果:13 ## 变量为非字符串和数字,可以直接修改全局变量
b = [1,2,3]
def func():
b = [4,5,6]
return b print(func()) 运行结果:
[4,5,6]

nonlocal 关键字:

  1、不能修改全局变量;

  2、在局部作用域中,对父级作用域(或者更外层的作用域非全局作用域)的变量进行引用和修改,此层及以下的变量全部发生改变。

 b = 1                     ## 全局变量
def func1():
b = 2
print(b) ## b = 2
def func2():
nonlocal b ## 引用上一级的变量 b
print(b) ## b = 2
def func3():
print(b) ## b = 2 func3()
func2()
func1()
print(b) 运行结果: 2
2
2
1

2、函数名 === 第一类对象

 1) 函数名的内存地址

 def func():
print(11)
print(func) ## <function func at 0x0000000002FFC158>
6 print(id(func)) ## 50315608 函数的内存地址
运行结果:

<function func at 0x0000000002FFC158>
50315608

2) 函数名赋值给其他变量 def func():
## 将函数名func赋值给func1
print(11)
func1 = func
func1()

运行结果: 3) 函数名可以当做容器内的元素(循环执行函数) def func1():
print(11)
def func2():
print(22)
def func3():
print(33)
def func4():
print(44)
list = [func1,func2,func3,func4]
for i in list:
i()

运行结果:
11
22
33
44 4) 函数名可以当做函数的参数 def func1():
print(111)
def func2(a):
pass
func2(func1())

运行结果:
111 5) 函数名可以当做函数的返回值 def func1():
print(111)
def func2(a):
return a
func2(func1())

运行结果:

3、闭包

闭包:内层函数对外层函数(非全局)的变量的引用

1)闭包函数 a = 1
def func1():
b = 2
def func2():
c = b ### 内层函数引用非全局的外层函数变量,是闭包函数
return c
ret = func2()
print(ret)
print(func2.__closure__)
func1()

运行结果: (<cell at 0x0000000002D87498: int object at 0x000000001D62EC90>,) 2)非闭包函数 a = 1
def func1():
b = 2
def func2():
print(a) ### 内存函数引用全局变量,不是闭包函数
func2()
print(func2.__closure__)
func1()

运行结果: None 3)检测是否为闭包函数 def func1(x):
def func2(): ### func2 为闭包函数
return x
ret = func2()
print(ret)
print(func2.__closure__) ### 检测函数是否是闭包函数(返回cell就是闭包函数,返回none则不是闭包)
func1(1) 运行结果:
1
(<cell at 0x0000000002BF7498: int object at 0x000000001D5CEC70>,) 4)闭包函数的应用 def wrapper():
money = 1000
def func():
name = "eva"
def inner():
print(name,money)
return inner()
return func()
f = wrapper()

运行结果:
eva 1000

5)闭包的用处:若内存函数是个闭包,python内部有个机制,
遇到闭包,会在内存中开启一个内存空间,不会随着函数的结束而关闭 from urllib.request import urlopen def pachong(url):
content = urlopen(url).read()
def get(): ### 通过闭包函数的特性节俭资源
with open("爬虫","ab") as f:
f.write(content)
return get ### 执行内层函数
pachong("https://www.cnblogs.com/")() 6)拓展 1、执行内层函数的两种方式:
  1)返回内层函数的函数值 def wrapper():
def inner():
print(66)
return inner
wrapper()()
# 执行顺序:先调用函数wrapper(),返回 inner,再调用函数inner(),打印内部函数inner()

运行结果:
66   2)直接调用内部函数 def wrapper():
def inner():
print(66)
inner()
wrapper()

运行结果:

【python 3】 函数 进阶的更多相关文章

  1. 【转】Python之函数进阶

    [转]Python之函数进阶 本节内容 上一篇中介绍了Python中函数的定义.函数的调用.函数的参数以及变量的作用域等内容,现在来说下函数的一些高级特性: 递归函数 嵌套函数与闭包 匿名函数 高阶函 ...

  2. 《Python》 函数进阶和名称空间作用域

    函数进阶: 一.动态参数:*args  **kwargs *args是元祖形式,接收除去键值对以外的所有参数 # args可以换成任意变量名,约定俗成用args **kwargs接收的只是键值对的参数 ...

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

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

  4. Python之函数进阶

    本节内容 上一篇中介绍了Python中函数的定义.函数的调用.函数的参数以及变量的作用域等内容,现在来说下函数的一些高级特性: 递归函数 嵌套函数与闭包 匿名函数 高阶函数 内置函数 总结 一.递归函 ...

  5. python开发函数进阶:生成器表达式&各种推导式

    一,生成器表达式 #生成器表达式比列表解析更省内存,因为惰性运算 #!/usr/bin/env python #_*_coding:utf-8_*_ new_2 = (i*i for i in ran ...

  6. day09 python之函数进阶

    楔子 假如有一个函数,实现返回两个数中的较大值: def my_max(x,y): m = x if x>y else y return mbigger = my_max(10,20)print ...

  7. Python入门-函数进阶

    昨天我们简单的了解了函数的定义,调用,以及传参,其实还有一个更重要的传参:动态传参,让我们继续昨天没有说完的,以及今天我要分享的东西. 一.动态传参 之前我们说过了传参,如果我们需要给一个函数传参,而 ...

  8. python学习——函数进阶

    首先来看下面这个函数. def func(x,y): bigger = x if x > y else y return bigger ret = func(10,20) print(ret) ...

  9. python开发函数进阶:装饰器

    一,装饰器本质 闭包函数 功能:就是在不改变原函数调用方式的情况下,在这个函数前后加上扩展功能 作用:解耦,尽量的让代码分离,小功能之前的分离. 解耦目的,提高代码的重用性 二,设计模式 开放封闭原则 ...

  10. python开发函数进阶:匿名函数

    一,匿名函数 #简单的需要用函数去解决的问题 匿名函数的函数体 只有一行#也叫lambda表达式# cal2(函数名) = lambda n(参数) : n*n(参数怎么处理,并且返回值)#参数可以有 ...

随机推荐

  1. 学号20175313 《实现Linux下od -tx -tc XXX的功能》第九周

    目录 MyOD 一.题目要求 二.题目理解 三.需求分析 四.设计思路 五.代码链接 六.代码实现过程中遇到的问题 七.运行结果截图 八.参考资料 MyOD 一.题目要求 编写MyOD.java 用j ...

  2. C#基础加强(9)之对象序列化(二进制)

    介绍 对象序列化是将对象转换为二进制数据(字节流),反序列化是将二进制数据还原成对象.对象的非持久态的,不仅在程序重启.操作系统重启会造成对象的丢失,就是退出函数范围等都可能造成对象的消失,而序列化与 ...

  3. GBDT总结

    一.简介 gbdt全称梯度下降树,在传统机器学习算法里面是对真实分布拟合的最好的几种算法之一,在前几年深度学习还没有大行其道之前,gbdt在各种竞赛是大放异彩.原因大概有几个,一是效果确实挺不错.二是 ...

  4. ionic3 小记录

    cordova platform add ios@latest 安装最新ios ionic cordova build ios -- --buildFlag="-UseModernBuild ...

  5. 尝试启动 ADB 服务器时出错 解决方法

    启动CMD→ adb kill-server → adb start-server;

  6. REDHAT YUM本地源的搭建和使用

    yum源一般分为两种,本地yum源和本地网络yum源,前者是通过文件提供安装包,后者是通过网络下载安装包: 由于Redhat7.3的yum源需要注册付费,所以往往会出现下载yum源安装包失败,如下图: ...

  7. 编年史:OI测试

    2019.4.18 t1:给出不定方程ax+by+c=0,求x在x1~x2并且y在y1~y2时的解个数.考场上想的是一个扩欧板子敲下去,然后构造出x>=x1的最小解,同时得出y,然后通过通项来枚 ...

  8. 构建RN或Weex项目时,使用Android Studio常遇到的问题

    1 . androidStudio报错No cached version available for offline mode 解决方法 原因是之前为了提高编译速度,在Gradle设置选项中开启了Of ...

  9. JDK8 HashMap--removeNode()移除节点方法

    /*删除节点*/ final Node<K,V> removeNode(int hash, Object key, Object value, boolean matchValue, bo ...

  10. openGL实现图形学扫描线种子填充算法

    title: "openGL实现图形学扫描线种子填充算法" date: 2018-06-11T19:41:30+08:00 tags: ["图形学"] cate ...