函数进阶

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. idea+maven下jrebel的安装破解

    链接地址:https://www.cnblogs.com/wang1024/p/7211194.html

  2. readlink 获取进程的绝对路径

    readlink可以获取exe所在的路径(直接和进程关联);无法获得so的路径,so路径可以用dladdr,参考另一篇文章linux系统中有个符号链接:/proc/self/exe 它代表当前程序,所 ...

  3. leetcode148. Sort List

    和数组里面的归并排序相同,用两个指针分别对应low high,递归进行归并排序然后merge把两个链表合在一起 /** * Definition for singly-linked list. * s ...

  4. c# 有序链表合并 链表反转

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. C#设计模式(13)——代理模式(Proxy Pattern)(转)

    一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代 ...

  6. SQL的优化整理

    1,对查询进行优化,要尽量避免全表扫描,首先应考虑在进行条件判断的字段上创建索引 (注意:如果一张数据表中的数据更新频率太高,更新数据之后需要重新创索引,这个过程很耗费性能,所以更新频率高的数据表慎用 ...

  7. 日常开发工作常用linux命令

    :wq 保存退出 :q! 强制退出 vi 查看 vim 编辑 rpm -qa|grep jdk 命令查看当前的jdk情况 yum -y remove java java-1.7.0-openjdk* ...

  8. 2018-2019-2 20165335『网络对抗技术』Exp5:MSF基础应用

    主动攻击的实践: ms17_010(成功) 浏览器攻击的实践:ms14_064(成功) 客户端攻击的实践:adobe reader PDF的攻击(成功) 运用辅助模块的实践:VNC弱口令破解/绕过(失 ...

  9. Python 嘉宾列表问题

    某书上的练习题,当作复习8 #3-5 修改嘉宾名单 def alter(someone, other): if someone in din_list: din_list.remove(someone ...

  10. svn基础了解

    Apache Subversion 通常被缩写成 SVN,是一个开放源代码的版本控制系统 Subversion(SVN) 是一个开源的版本控制系統, 也就是说 Subversion 管理着随时间改变的 ...