1,python中,名称空间分三种:

  1. 全局命名空间

  2. 局部命名空间(临时命名空间)

  3. 内置名称空间

2,作用域(两种):

   1,全局作用域  包含:全局名称空间   内置名称空间

   2,局部作用域  包含:局部命名空间

  2.1,取值顺序:

    就近原则:局部名称空间 --> 全局名称空间 --> 内置名称空间   单向从小到大范围

  2.2, 加载顺序:

    内置名称空间 --> 全局名称空间(当程序执行时) -- > 局部名称空间(当函数调用的时候)

3,函数的嵌套:

  

def func1():
print(111)
def func2():
print(222)
func1()
print(333)
print(666)
func2()
print(555)

例子1

def func1():
print(222)
def func2():
print(333)
print(111)
func2()
print(666)
func1() # 执行结果:
222 111 333 666

例子2

4,global   nonlocal

  局部名称空间对全局名称空间的变量可以引用,但是不能改变。

count = 1
def func1():
count = 2
print(count)
func1()
count = 1
def func1():
# count = 3
count = count + 1 # local variable 'count' referenced before assignment
print(count)
func1()

报错

报错原因: 如果你在局部名称空间 对一个变量进行修改,那么解释器会认为你的这个变量在局部中已经定义了,但是对于上面的例题,局部中没有定义,所以他会报错,

  global

    1,在局部名称空间声明一个全局变量。

声明

    2,在局部名称空间声明可以对全局变量进行修改。

count = 1
def func1():
global count
count = count + 1
print(count)
func1()
print(count)

修改

  nonlocal

    1,子函数对父函数的变量进行修改。

    2,此变量不能是全局变量

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

def func1():
count = 666
def inner():
print(count)
def func2():
nonlocal count
count += 1
print("func2",count)
func2()
print("inner",count)
inner()
print("funcl",count)
func1() # 运行结果:
666
func2 667
inner 667
funcl 667

global

5,函数的应用

  1,函数名就是函数的内存地址。

def func():
pass
print(func) # <function func at 0x05958660>

  2,函数名可以作为变量。

def func1():
print(666)
f1 = func1
f2 = f1
f2()

  3,函数名可以作为函数的参数。

def func():
print(666)
def func1():
func()
def func2(x):
x()
func2(func1)

  4,函数名可以当作函数的返回值。

def wraaper():
def inner():
print("inner")
return inner
ret = wraaper()
ret()

  5,函数名可以当作为容器类类型的元素。

def func1():
print("in func1")
def func2():
print("in func2")
def func3():
print("in func3")
def func4():
print("in func4")
l1 = [func1,func2,func3,func4]
for i in l1:
i()

     向上面的函数名这种,第一个类对象。

6,globals()   locals()

  1,globals()  返回全局变量的一个字典。

  2,locals()   返回当前位置的局部变量的字典。

def funcl():
a = 2
b = 3
# print(globals())
# print(locals())
def inner():
c = 5
d = 6
print(globals())
print(locals())
inner()
print(globals())
print(locals())
funcl()

7,闭包

    --内层函数对外层函数的变量(非全局变量)的引用,并返回。这样就形成了闭包。

  1,迭代器的条件:

      1,必须要有函数嵌套。

      2,内层函数必须要引用外层函数中的变量(不能是全局变量)。

      3,外层函数必须返回内部中的函数名(引用)。
    
def wraaper():
n = 1
def inner():
nonlocal n
n += 1
return n
# inner()
return inner
f = wraaper()
print(f())
print(f())

闭包

  2,闭包的作用:

      当程序执行时,遇到了函数执行,他会在内存开辟一个空间,局部名称空间,

      如果这个函数内部形成了闭包,

      那么他就不会随着函数的结束而消失。

# 1,写装饰器的时候用。
# 2,写爬虫的时候用。 from urllib.request import urlopen def index():
url = "http://www.xiaohua100.cn/index.html"
def get():
return urlopen(url).read()
return get xiaohua = index() # get
content = xiaohua() # get()
content = xiaohua() # get()
print(content.decode('utf-8'))

作用

8,迭代器

  1,可迭代对象

    对象内部含有__iter__方法的就是可迭代对象。

    可迭代对象满足可迭代协议。

  2,判断是否是可迭代对象。

    

dic = {"name":"alex"}
print('__iter__' in dir(dic))

方法一

from collections import Iterable
from collections import Iterator
print(isinstance("alex",Iterable))
print(isinstance('alex',Iterator))
print(isinstance("alex",str))

方法二

  3,可迭代对象 vs 迭代器

    可迭代对象不能取值,迭代器是可以取值的。

    可迭代对象 可以转化成迭代器。

lis = [1,2,3]  # 可迭代对象
itet = lis.__iter__() #迭代器
itet = iter(lis) # 迭代器
print(itet)

    可迭代器如何取值?

      next一次,取值一次

      1,可迭代对象不能取值,迭代器是可以取值的。

      2,迭代器非常节省内存。

      3,迭代器每次只会取一个值。

      4,迭代器是单向的从上至下地取值,一条路走到头。

    1,迭代器原理

      1,将可迭代对象转化成迭代器。

      2,调用__next__方法取值。

      3,利用异常处理停止报错。

s1 = "asdfg"
iter1 = s1.__iter__()
while 1:
try:
print(iter1.__next__())
except StopIteration:
break
s1 = "asdfg"

# l1 = [i for i in range(100)]
# print(11) ret = (i for i in range(10000))
print(ret.__next__())
print(ret.__next__())
print(ret.__next__())

9, 生成器

    --就是自己python用代码写的迭代器,生成器的本质就是迭代器。

  1,构建一个生成器的两种方式:

      1,通过生成器函数。

      2,生成器表达式。

   生成器函数:

def func1(x):
x += 1
return x
func1(5) # 函数的执行命令,并且接受函数的返回值
print(func1(5))

函数

def func1(x):
x += 1
print(111)
print(111)
print(111)
yield x
x += 2
print(222)
yield "alex"
x += 3
g_obj = func1(5) # 生成器函数对象
# print(g_obj)
# print(g_obj.__next__())
print(g_obj.__next__())

生成器函数

    一个 naxt 对应一个 yield

    yield 将值返回给生成器对象 .__next__()

    yield 和 return区别

    return 结束函数,给函数的执行者返回值

    yield  不会结束函数,一个next 对应一个yield,给生成器对.__next__()返回值。

    

    生成器函数 和 迭代器 区别

      1,自定制的区别

# li = [1,2,3,4,5]
# li.__iter__() def func1(x):
x += 1
yield x
x += 3
yield x
x += 5
yield x
g1 = func1(5)
print(g1.__next__())
print(g1.__next__())
print(g1.__next__())

区别1

      2,内存级别的区别

      迭代器是需要可迭代对象进行转化。可迭代对象非常占内存。

      生成器直接创建,不需要转化,从本质就节省内存。

def func1():
for i in range(10000):
yield i g1 = func1()
for i in range(50):
print(g1.__next__()) # ————————————————————————
def func1():
print(1)
count = yield 6
print(count)
print(2)
count1 = yield 7
print(count1)
print(3)
yield 8 g = func1()
next(g)
g.send("alex")
# g.send("太白")
print(g.__next__())

区别二

    

     send   与   naxt   区别

      send与next一样,也是对生成器取值(执行一个yield)的方法。

      send可以给上一个yield传值。

      第一次取值永远都是next。

      最后一个yield永远也得不到send传的值。

# 函数
def cloth1(n):
for i in range(n+1):
print("衣服%s号" % i)
cloth1(1000)
# --------------------------------
# 生成器函数
def cloth1(n):
for i in range(1,n+1):
yield ("衣服%s号" % i)
g = cloth1(1000)
for i in range(50):
print(g.__next__())
# for i in range(50):
# print(g.__next__())

函数 vs 生成器

   列表推导式:

      -- 一行代码几乎搞定你需要的任何的列表。

      优点:一行解决,方便

      缺点:容易着迷,不易排错,不能超过三次循环。

     列表推导式不能解决所有列表问题,所以不要太刻意用。

    循环模式   [变量(加工后的变量)for 变量 initerable]

l = [i for i in range(1,101)]
print(l) l2 = print(["python%s期" % i for i in range(1,11)]) print([i*i for i in range(1,11)])

循环模式

    筛选模式  [变量(加工后的变量)in iterable if 条件]

l3 = [i for i in range(1,31) if i % 2 == 0]
print(l3) print([i for i in range(1,31) if i % 3 == 0]) print([i**2 for i in range(1,31) if i % 3 == 0]) names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
# 请选出名字中带两个e的 print([j for i in names for j in i if j.count("e") == 2])

筛选模式

   生成器表达式: 将列表推导式的 [ ] 换成 ( ) 即可。

g = (i for i in range(100000))
print(g)
print(g.__next__())
print(g.__next__())
for i in range(20): # 循环取取值
print(g.__next__())

生成器表达式

mcase = {"a":10,"b":34}
mcase_frequency = {mcase[k]: k for k in mcase} # 将键值对反转
print(mcase_frequency)

元组表达式

squared = {x**2 for x in [1,-1,2]} # 将集合去重
print(squared)

集合表达式

python成长之路七-函数的进阶的更多相关文章

  1. python成长之路六-函数的初识

    定义函数 我们现学已知的python函数有<内置函数> 而我们现在要学的是<自定义函数> 1,def  定义一个函数 def name(): # 后接函数名 冒号 pass 2 ...

  2. (转)Python成长之路【第九篇】:Python基础之面向对象

    一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...

  3. 【Python成长之路】Python爬虫 --requests库爬取网站乱码(\xe4\xb8\xb0\xe5\xa)的解决方法【华为云分享】

    [写在前面] 在用requests库对自己的CSDN个人博客(https://blog.csdn.net/yuzipeng)进行爬取时,发现乱码报错(\xe4\xb8\xb0\xe5\xaf\x8c\ ...

  4. 【Python成长之路】装逼的一行代码:快速共享文件

    [Python成长之路]装逼的一行代码:快速共享文件 2019-10-26 15:30:05 华为云 阅读数 335 文章标签: Python编程编程语言程序员Python开发 更多 分类专栏: 技术 ...

  5. python成长之路第三篇(1)_初识函数

    目录: 函数 为什么要使用函数 什么是函数 函数的返回值 文档化函数 函数传参数 文件操作(二) 1.文件操作的步骤 2.文件的内置方法 函数: 一.为什么要使用函数 在日常写代码中,我们会发现有很多 ...

  6. Python 成长之路

    Python roadmap python 基础 ... 内置常用函数.三元运算.递归 迭代器和生成器 模块和常用的模块 面向对象 对向对象进阶 网络编程 并发编程 ... 数据库 MySQL pym ...

  7. 我的Python成长之路---第一天---Python基础(1)---2015年12月26日(雾霾)

    2015年12月26日是个特别的日子,我的Python成之路迈出第一步.见到了心目中的Python大神(Alex),也认识到了新的志向相投的伙伴,非常开心. 尽管之前看过一些Python的视频.书,算 ...

  8. python成长之路【第十八篇】:python模块介绍、模块导入和重载

    一.模块和命名空间 一般来说,Python程序往往由多个模块文件构成,通过import语句连接在一起.每个模块文件是一个独立完备的变量包,即一个命名空间.一个模块文件不能看到其他文件定义的变量名,除非 ...

  9. Python成长之路第二篇(1)_数据类型内置函数用法

    数据类型内置函数用法int 关于内置方法是非常的多这里呢做了一下总结 (1)__abs__(...)返回x的绝对值 #返回x的绝对值!!!都是双下划线 x.__abs__() <==> a ...

随机推荐

  1. python多版本共存问题(以2.7和3.5系列版本为例)

    1.0 下载Python2.7x和Python3.5x版本 2.0 安装Python 3.0 配置环境变量,分别添加至path路径 4.0 只修改Python27文件中的.exe文件(这样系统默认为P ...

  2. Apache cxf暴露接口以及客户端调用之WebService初步理解

    在我们真实的项目中,经常会调用别人提供给我们的接口,或者在自己的团队中, restful风格的前后端分离也经常会提供一个后端接口暴露出去供app,或者.net/C/C++程序员去调用,此时就需要使用到 ...

  3. xml文件里 用js语句获取 当前时间

    获取当前时间的代码:xml文件中 <td><div align="center"><br/><strong>送检时间</str ...

  4. Bootstrap栅栏布局里col-xs-*、col-sm-*、col-md-*、col-lg-*之间的区别及使用方法

    原文:Bootstrap栅栏布局里col-xs-*.col-sm-*.col-md-*.col-lg-*之间的区别及使用方法 版权声明:本文为博主原创文章,未经博主允许不得转载. https://bl ...

  5. 51nod 1295 XOR key 可持久化01字典树

    题意 给出一个长度为\(n\)的正整数数组\(a\),再给出\(q\)个询问,每次询问给出3个数,\(L,R,X(L<=R)\).求\(a[L]\)至\(a[R]\)这\(R-L+1\)个数中, ...

  6. Error【0007】:zabbix中因为curl版本过低而无法发送邮件

    1. 错误背景 在centos6.5上,源码部署zabbix最新版本zabbix-3.2.14.部署后之后,在配置邮件发送报警时出错 2. 错误提示 3. 原因分析 从网上检索的结果是说,系统中的cu ...

  7. TDD、BDD、ATDD、DDD 软件开发模式

    TDD.BDD.ATDD.DDD 软件开发模式 四个开发模式意思: TDD:测试驱动开发(Test-Driven Development) BDD:行为驱动开发(Behavior Driven Dev ...

  8. Webpack 2 视频教程 002 - NodeJS 安装与配置

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...

  9. Jvm远程监控

    服务器运行新建文件 : udi.policy grant codebase "file:${java.home}/../lib/tools.jar" { permission ja ...

  10. Scrum Meeting 5

                第五次会议 No_00:工作情况 No_01:任务说明 待完成 已完成 No_10:燃尽图 No_11:照片记录 待更新 No_100:代码/文档签入记录 No_101:出席表 ...