python自动化day4-函数嵌套、名称空间、作用域、装饰器
1.函数嵌套
#函数的镶套调用:在调用一个函数的过程中,又调用其他函数
def max2(x,y):
if x > y:
return x
else:
return y
def max4(a,b,c,d):
res1=max2(a,b)
res2=max2(res1,c)
res3=max2(res2,d)
return res3
print(max4(1,2,3,-1))
#函数的嵌套定义:在一个函数的内部又定义了另一个函数
def f2():
print('from f2')
def f1():
x=1
# def f2()
# print('from f2')
f2()
f1()
2.名称空间
存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方
#名称空间的加载顺序
#python test.py#1、python解释器先启动,因而首先加载的是:内置名称空间#2、执行test.py文件,然后以文件为基础,加载全局名称空间#3、在执行文件的过程中如果调用函数,则临时产生局部名称空间
#内置名称空间:在python解释器启动时产生,存放一些python内置的名字#全局名称空间:在执行文件时产生,存放文件级别定义的名字
#局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的局部名称空间#用来存放该函数内定义的名字,该名字在函数调用时生效,在函数调用结束后失效
加载顺序
内置---》全局---》局部
优先掌握一
名字的查找顺序是:局部-》全局-》内置
def foo():
max= #内置
foo()
print(max)
###########################得到的是全局
<built-in function max>
x=0
def f1():
x=1
def f2():
x=2
def f3():
x=3
print(x)
f3()
f2()
print(x)
f1()
--------------------------------->
3
1
作用域:作用的范围
全局作用域:全局存活,全局有效:globals()
max=1111111
def f1():
def f2():
def f3():
def f4():
print(max)
f4()
f3()
f2()
局部作用域:临时存活,局部有效:locals()
#global nonlocal掌握
x=1
def f1():
global x
x=2
f1()
print(x)
l=[]
def f2():
l.append('f2')
f2()
print(l)
x=0
def f1():
x=1
def f2():
x=2
def f3():
# global x
nonlocal x
x=3
f3()
f2()
print(x)
f1()
print(x)
优先掌握二作用域关系,在函数定义时就已经固定 ,于调用位置无关,在调用函数时,必须必须必须回到函数原来定义的位置去找作用域关系
x=1
def f1():
def f2():
print(x)
return f2
x=100
def f3(func):
x=2
func()
x=10000
f3(f1())
查看作用域:globals(),locals()
LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__ locals 是函数内的名字空间,包括局部变量和形参 enclosing 外部嵌套函数的名字空间(闭包中常见) globals 全局变量,函数定义所在模块的名字空间 builtins 内置模块的名字空间
3.闭包函数
定义在函数内部的函数,包含对外部作用域名字的引用,而不是对全局作用域名字的引用,那么该内部函数称为闭包函数
x=1
def f1():
x = 11111111
def f2():
print(x)
return f2
func = f1()
func()
闭包函数的应用:惰性计算
import requests
def index():
url='https://www.python.org'
def get():
print(requests.get(url).text)
return get
webb=index()
webb()
4.装饰器
装饰器就是闭包函数的一种应用场景
一 为何要用装饰器
开放封闭原则:对修改封闭,对扩展开放
二 什么是装饰器
装饰他人的工具:本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
装饰器的语法
被装饰函数的正上方,单独一行
@deco1
@deco2
@deco3
def foo():
pass
foo=deco1(deco2(deco3(foo)))
import time
def index():
time.sleep(3)
print('hellow world!')
def ti(x):
#x=index
def www():
start=time.time()
x()
stop=time.time()
print('sdsadAdsd %s' %(stop-start))
return www
index=ti(index)
index()
#########简单写法
import time
def ti(x):
def www():
start=time.time()
x()
stop=time.time()
print('sdsadAdsd %s' %(stop-start))
return www
@ti #idex=ti(index)
def index():
time.sleep(3)
print('hellow world!')
index()
简单写法
def auth(driver='file'):
def auth2(func):
def wrapper(*args,**kwargs):
name=input("user: ")
pwd=input("pwd: ")
if driver == 'file':
':
print('login successful')
res=func(*args,**kwargs)
return res
elif driver == 'ldap':
print('ldap')
return wrapper
return auth2
@auth(driver='file')
def foo(name):
print(name)
foo('egon')
有参数装饰器
import time
def timmer(func):
def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return res
return wrapper
@timmer
def foo():
time.sleep(3)
print('from foo')
foo()
无参装饰器
装饰器查看注释
from functools import wraps
def deco(func):
@wraps(func) #加在最内层函数正上方
def wrapper(*args,**kwargs):
return func(*args,**kwargs)
return wrapper
@deco
def index():
'''哈哈哈哈'''
print('from index')
print(index.__doc__)
装饰多个函数
# 叠加多个装饰器 # 1. 加载顺序(outter函数的调用顺序):自下而上 # 2. 执行顺序(wrapper函数的执行顺序):自上而下
def outter1(func1): #func1=wrapper2的内存地址
print('加载了outter1')
def wrapper1(*args,**kwargs):
print('执行了wrapper1')
res1=func1(*args,**kwargs)
return res1
return wrapper1
def outter2(func2): #func2=wrapper3的内存地址
print('加载了outter2')
def wrapper2(*args,**kwargs):
print('执行了wrapper2')
res2=func2(*args,**kwargs)
return res2
return wrapper2
def outter3(func3): # func3=最原始的那个index的内存地址
print('加载了outter3')
def wrapper3(*args,**kwargs):
print('执行了wrapper3')
res3=func3(*args,**kwargs)
return res3
return wrapper3
@outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
@outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
@outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
def index():
print('from index')
print('======================================================')
index()
示范代码
迭代器
#迭代是一个重复的过程,每一次重复,都是基于上一次的结果而来
l=['a','b','c','d']
count=0
while count < len(l): #迭代
print(l[count])
count+=1
#迭代对象:凡是对象下游__iter__方法:对象.__iter__,该对象就是迭代对象#所有字符串类型,列表,字典,元组等等都是
dic={'name':'zbb','sex':'m','age':8}
i=dic.__iter__()
# print(i)
# i.__next__() #next(i)
print(next(i))
print(next(i))
print(next(i))
print(next(i)) #StopIteration
l=[1,2,3,4,5,6] i=l.__iter__() print(i) i1=i.__iter__() print(i1) <list_iterator object at 0x0000024138121518> <list_iterator object at 0x0000024138121518>
迭代器一种不依赖索引的取值方式
l=[1,2,3,4,5,6] i=l.__iter__() print(next(i)) print(next(i)) print(next(i)) print(next(i))
#取列表
l=['1',2,3,4,5,6]
xz=iter(l)
while True:
try:
print(next(xz))
except StopIteration:
break
取出字典
dic={'name':'zbb','sex':'m','age':8}
zzx=iter(dic)
while True:
try:
#print(next(zzx))
k=next(zzx)
print(k,dic[k])
except StopIteration:
break
#什么是迭代器对象#有 __iter__,执行得到的仍是迭代本身#y有 __next__ #迭代器对象的优点#提供一种统一的(不依赖索引的)迭代方式#迭代器本身,比起其他数据类型更省内存
with open('a.txt') as f:
print(next(f))
print(next(f))
print(next(f))
#迭代器的缺点#一次性,只能往后走,不能回退,不如索引取值灵活、#无法预知什么时候结束,既无法预知长度
l=[1,2,3,4,5] i=iter(l) print(next(i)) print(next(i)) print(next(i))
#for循坏原理
l=[1,2,3,4,5,5]
for item in l:#==iter_l=l.__iter__()
print(item)
#补充:判断可迭代对象与迭代器对象(了解)
from collections.abc import Iterable,Iterator
s='hello'
l=['a','b','c','d']
t=('a','b','c','d')
dic={'name':'egon','sex':'m',"age":18}
set1={1,2,3}
f=open('a.txt')
# print(isinstance(s,Iterable))
# print(isinstance(l,Iterable))
# print(isinstance(t,Iterable))
# print(isinstance(dic,Iterable))
# print(isinstance(set1,Iterable))
# print(isinstance(f,Iterable))
print(isinstance(s,Iterator))
print(isinstance(l,Iterator))
print(isinstance(t,Iterator))
print(isinstance(dic,Iterator))
print(isinstance(set1,Iterator))
print(isinstance(f,Iterator))
生成器
#只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码 #生成器就是迭代器 #yield的功能:1、把函数的结果做成迭代器(以一种优雅的方式封装好__iter__,__next__) #y函数暂停与再继续运行的状态是由yield决定 以挂起/保存函数的运行状态
def func():
print('====>first')
yield 1
print('====>second')
yield 2
print('====>third')
yield 3
print('====>end')
g=func()
print(g) #<generator object func at 0x0000000002184360>
next(g)
print(next(g)) #可以打印yield
for i in g:
# pass
print(i)
def func(n):
print("wee")
while True:
yield n
n+=1
g=func(1)
print(next(g))
print(next(g))
for i in g:
print(i)
for i in range(1000000000000000000000):
print(i)
def my_range(start,stop):
while True:
if start == stop:
raise StopIteration
yield start
start+=1
# g=my_range(1,3)
# print(next(g))
# print(next(g))
# print(next(g))
#自己写一个range
# for i in my_range(1,2):
# print(i)
yield与return的比较
#都有返回值功能#return 只能返回一次,yield可以返回多次值
面向过程编程 #1、首先强调:面向过程编程绝对不是用函数编程这么简单,面向过程是一种编程思路、思想,而编程思路是不依赖于具体的语言或语法的。言外之意是即使我们不依赖于函数,也可以基于面向过程的思想编写程序 #2、定义 面向过程的核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么 基于面向过程设计程序就好比在设计一条流水线,是一种机械式的思维方式 #3、优点:复杂的问题流程化,进而简单化 #4、缺点:可扩展性差,修改流水线的任意一个阶段,都会牵一发而动全身 #5、应用:扩展性要求不高的场景,典型案例如linux内核,git,httpd #6、举例 流水线1: 用户输入用户名、密码--->用户验证--->欢迎界面 流水线2: 用户输入sql--->sql解析--->执行功能 ps:函数的参数传入,是函数吃进去的食物,而函数return的返回值,是函数拉出来的结果,#面向过程的思路就是,把程序的执行当做一串首尾相连的功能,该功能可以是函数的形式,然后一个函数吃,拉出的东西给另外一个函数吃,另外一个函数吃了再继续拉给下一个函数吃。。。
#=============复杂的问题变得简单
#注册功能:
#阶段1: 接收用户输入账号与密码,完成合法性校验
def talk():
while True:
username=input('请输入你的用户名: ').strip()
if username.isalpha():
break
else:
print('用户必须为字母')
while True:
password1=input('请输入你的密码: ').strip()
password2=input('请再次输入你的密码: ').strip()
if password1 == password2:
break
else:
print('两次输入的密码不一致')
return username,password1
#阶段2: 将账号密码拼成固定的格式
def register_interface(username,password):
format_str='%s:%s\n' %(username,password)
return format_str
#阶段3: 将拼好的格式写入文件
def handle_file(format_str,filepath):
with open(r'%s' %filepath,'at',encoding='utf-8') as f:
f.write(format_str)
def register():
user,pwd=talk()
format_str=register_interface(user,pwd)
handle_file(format_str,'user.txt')
register()
#=============牵一发而动全身,扩展功能麻烦
#阶段1: 接收用户输入账号与密码,完成合法性校验
def talk():
while True:
username=input('请输入你的用户名: ').strip()
if username.isalpha():
break
else:
print('用户必须为字母')
while True:
password1=input('请输入你的密码: ').strip()
password2=input('请再次输入你的密码: ').strip()
if password1 == password2:
break
else:
print('两次输入的密码不一致')
role_dic={
':'user',
':'admin'
}
while True:
for k in role_dic:
print(k,role_dic[k])
choice=input('请输入您的身份>>: ').strip()
if choice not in role_dic:
print('输入的身份不存在')
continue
role=role_dic[choice]
return username,password1,role
#阶段2: 将账号密码拼成固定的格式
def register_interface(username,password,role):
format_str='%s:%s:%s\n' %(username,password,role)
return format_str
#阶段3: 将拼好的格式写入文件
def handle_file(format_str,filepath):
with open(r'%s' %filepath,'at',encoding='utf-8') as f:
f.write(format_str)
def register():
user,pwd,role=talk()
format_str=register_interface(user,pwd,role)
handle_file(format_str,'user.txt')
register()
#ps:talk内对用户名\密码\角色的合法性校验也可以摘出来做成单独的功能,#但本例就写到一个函数内了,力求用更少的逻辑来为大家说明过程式编程的思路
python自动化day4-函数嵌套、名称空间、作用域、装饰器的更多相关文章
- Python自动化面试必备 之 你真明白装饰器么?
Python自动化面试必备 之 你真明白装饰器么? 装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,所以这也是Python面试中必问的问题,但对于好多小白来讲,这个功能 有点绕 ...
- Python 函数对象-函数嵌套-名称空间与作用域-闭包函数
今日内容: 1. 函数对象 函数是第一类对象: 指的是函数名指向的值可以被当中数据去使用 1.可以被引用 2.可以当做参数传给另一个函数 3.可以当做一个函数的返回值 4.可以当做容器类型的元素 2. ...
- Python入门之函数的嵌套/名称空间/作用域/函数对象/闭包函数
本篇目录: 一.函数嵌套 二.函数名称空间与作用域 三.函数对象 四.闭包函数 ============================================================ ...
- python12--字符串的比较 函数的默认值的细节 三元表达式 函数对象 名称空间 作用域 列表与字典的推导式 四则运算 函数的嵌套
复习 1.字符串的比较; 2.函数的参数; ******实参与形参的分类: 3.函数的嵌套调用: # 字符串的比较# -- 按照从左往右比较每一个字符,通过字符对应的ascii进行比较 ...
- python基础之函数参数,名称空间,以及函数嵌套
函数进阶内容梗概: 1. 函数参数--动态传参 2. 名称空间, 局部名称空间, 全局名称空间, 作⽤用域, 加载顺序. 3. 函数的嵌套 4. gloabal , nonlocal 关键字 1. 函 ...
- Python 入门基础10 --函数基础3 函数对象、名称空间、装饰器
今日内容 1.函数对象 2.名称空间与作用域 3.函数的嵌套调用与闭包 4.装饰器 一.函数对象 1.1 定义 函数名存放的就是函数地址,所以函数名也就是对象,称之为函数对象 1.2 函数对象的应用 ...
- day_12函数默认值,数据类型的补充,函数对象名称空间与作用域,函数的嵌套定义
复习, 昨天讲了字符串的比较,按照从左往右比较每一个字符,通过字符对应的ASCII码进行比较 函数的参数,‘ 实参与形参 形参:在函数定义时()中出现的参数 实参,在函数调用时()中出现的参数 实参的 ...
- Python记录9:函数4:名称空间作用域+闭包函数+装饰器
''' 一: 名称空间namespaces 名称空间就是存放名字与值绑定关系的内存空间 二: 名称空间分为三种 内置名称空间: 1. 特点: 存放是python解释器自 ...
- 函数的名称空间,函数的嵌套(global, nonlocal),函数名的运用
一 函数的名称空间 内置空间:存放python解释器内置函数的空间 全局空间:py文件运行时开辟的,存放的是执行的py文件(出去函数内部)的所有的变量与值的对用关系,整个py文件结束后才会消失. 局部 ...
- 十一. Python基础(11)—补充: 作用域 & 装饰器
十一. Python基础(11)-补充: 作用域 & 装饰器 1 ● Python的作用域补遗 在C/C++等语言中, if语句等控制结构(control structure)会产生新的作用域 ...
随机推荐
- N-Gram的数据结构
ARPA的n-gram语法如下: [html] view plaincopyprint? \data\ ngram 1=64000 ngram 2=522530 ngram 3=173445 \1-g ...
- 视觉SLAM漫淡(二):图优化理论与g2o的使用
视觉SLAM漫谈(二):图优化理论与g2o的使用 1 前言以及回顾 各位朋友,自从上一篇<视觉SLAM漫谈>写成以来已经有一段时间了.我收到几位热心读者的邮件.有的希望我介绍一下当前 ...
- POJ 1985 Cow Marathon (树形DP,树的直径)
题意:给定一棵树,然后让你找出它的直径,也就是两点中的最远距离. 析:很明显这是一个树上DP,应该有三种方式,分别是两次DFS,两次BFS,和一次DFS,我只写了后两种. 代码如下: 两次BFS: # ...
- 用word2013发布csdn博客
目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写 ...
- Halcon标定与自标定
Halcon标定:https://blog.csdn.net/niyintang/article/details/78752585 Halcon自标定:https://www.cnblogs.com/ ...
- eclipse使用配置
eclipse设置工作空间为UTF-8(适应中文,避免乱码) windows---preference---general---workspace,修改textfile encoding eclips ...
- 关于SoftReference的使用
SoftReference一般可以用来创建缓存的,缓存我们经常使用,例如:我们在浏览器中浏览了一个网页后,点击跳转到新的网页,我们想回去看之前的网页,一般是点击回退按钮,那么这个时候之前的网页一般就是 ...
- Awk使用方法简介
==================AWK=================== AWK简介:awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得 ...
- redis整理の安全认证
设置客户端连接后进行任何其他指定前需要使用的密码. tips:因为 redis 速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进 行 150K 次的密码尝试,这意味着你需要指定非常 ...
- SOLR企业搜索平台 二 (分词安装)
标签:linux lucene 分词 solr 全文检索 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://3961409.blog ...