今日概要:

  - 函数对象

  - 函数嵌套

  - 命名空间和作用域

  - 闭包

  - 装饰器

  - 迭代器

  - 生成器

  - 内置函数

一、函数对象

  1、函数对象的定义:

    函数是第一类对象,即函数可以当作数据传递

    可以被引用,可以被当作参数传递,可以当返回值,可以当做容器类型的元素

#1 可以被引用
def foo():
print('from foo') func=foo
print(foo) #函数对象
print(func)
func() #执行函数
#2 可以当做参数传递
def foo():
print('from foo') def bar(func):
print(func)
func() bar(foo)
#3 可以当返回值
def foo():
print('from foo') def bar(func):
return func f=bar(foo) print(f) f()
#4 可以做容器类型元素
def foo():
print('from foo')
dic={'func':foo} print(dic['func']) dic['func']()

  

 

  2、应用

def select():
print ('---select') def update():
print ('----update') dic_list = {'select':select,
'update':update
} def main():
while True:
sql = input('-->')
if not sql : continue l = sql.split(' ')
cmd = l[0]
if cmd in dic_list:
dic_list[cmd]() #直接通过函数名称加()进行执行 main()  

3、函数传可以传参数加默认形参数据类型 例子:backup: int

def test(sql,backup: int): #默认是backup是int类型,可以修改
print(type(sql))
print(type(backup))
print(sql,backup) if __name__ == '__main__':
test("select * from t1",123) """
<class 'str'>
<class 'int'>
select * from t1 123 """

  

二、函数嵌套

  1、函数的嵌套调用

#用嵌套函数求最大值
def max4(a,b,c,d):
res1=max(a,b)
res2=max(res1,c)
res3=max(res2,d)
return res3 print(max4(10,99,31,22))

    

  2、函数的嵌套定义

def f1():

    def f2():
print('from f2')
def f3():
print('from f3')
f3()
f2() # f1() #不允许在最外层调用最里层的函数
# f3() #会报错

  

  

三、命名空间和作用域

  1、命名空间

      名字的定义import time,  x='dragon',def black():,class black 这四类都是在定义名字

  2、三种名称空间

    内置名称空间(python解释器启动时会产生)

    print(sum)

    print(max)

#查看内置函数列表
import builtins
for i in dir(builtins):
print(i) 

  3、全局名称空间

    文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放到该空间

x=1

def func():
money=2000
x=2
print('func')
print(x) # x = 1
print(func)
func()
print(money) #不是全局命名空间不能输出 func()
print(x) 

  4、局部命名空间

    调用函数时会产生局部命名空间,只在函数调用时临时绑定,调用结束后解绑定

 

x=10000
def func():
x=1
def f1():
print (x)
f1()
func()

 

  5、作用域

    作用域分为全局作用域和局部作用域

    全局作用域:内置命名空间,全局命名空间

    局部作用域:局部作用空间

  6、作用域名字都查找顺序

    局部名称空间-->全局名称空间-->内置名称空间

  7、查看全局作用域和局部作用域的方法

    

#查看全局作用域内的名字:
print(gloabls())
#查看局局作用域内的名字:
print(locals())
x=1000
def func(y):
x=2
print(locals())
print(globals()) #局部比全局多一个x=2 func(1)

  

  8、总结:

   全局作用域:全局有效,在任何位置都能被访问到,除非del删掉,否则会一直存活到文件执行完毕

   局部作用域的名字:局部有效,只能在局部范围调用,只在函数调用时才有效,调用结束就失效

四、闭包

  1、闭包的定义

    定义在内部函数,包含对外部作用域而非全局作用域的引用,该内部函数称为闭包函数

例子:

def f1():
x = 1
def f2():
print(x) return f2 f=f1()
print(f)  

  2、应用,惰性计算

def f1():

    x = 1

    def f2():
print (x) return f2 f = f1() f() 

  3、

  

#__closure__方法,查看闭包函数下有多少个参数

#查看每个参数对应的值
oldboy.__closure__[0].cell_contents

 

x=1
# y=2
def f1():
# x=1
y=2
def f2():
print(x,y)
return f2 f=f1()
print(f.__closure__[0].cell_contents) 

五、装饰器

  1、装饰器的定义:装饰器是修饰别人的工具,工具指是函数,装饰器本身可以是任何可调用对象,被装饰的对象也可以是任意可调用对象

  2、用装饰器的原因:

  开放封闭原则:对修改是封闭的,对扩展是开放的
  装饰器就是为了在不修改被装饰对象的源代码以及调用方式的前提下,为其添加新功能

  3、无参装饰器,@为python的语法糖,装饰器遵循闭包规则  

import time

def timmer(func):
def wrapper():
start_time=time.time()
func() #index()
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return wrapper @timmer #index=timmer(index)
def index():
time.sleep(3)
print('welcome to index') f=timmer(index)
print(f)
f() #wrapper()---->index() index=timmer(index) #index==wrapper index() #wrapper()----->

  4、有参装饰器

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 #index=timmer(index)
def index():
time.sleep(3)
print('welcome to index')
return 1 @timmer
def foo(name):
time.sleep(1)
print('from foo') res=index() #wrapper()
print(res) res1=foo('dragon') #res1=wrapper('egon')
print(res1)

  5、应用

#用装饰器写用户登录,装饰器带参数传入
user_info = {'user':None,'user_status':False} def auth(driver = 'file'):
def auth1(func): def wrapper(*args,**kwargs):
if driver == 'file':
if user_info['user'] and user_info['user_status']:
res = func(*args,**kwargs)
return res
else: user_input = input('请输入帐号:')
user_pass = input('请输入密码:')
if user_input == 'alex' and user_pass == '123':
user_info['user'] = 'alex'
user_info['user_status'] = True
res = func(*args,**kwargs)
print ('login successfully')
return res
else:
print ('login error')
elif driver == 'mysql':
print ('------>mysql') return wrapper
return auth1 @auth('file') #auth1 == index = auth1(index) == index = wrapper
def index ():
print ('welcome login index')
@auth('mysql')
def home(name):
print ('%s welcome login home page' %(name)) index() home('alex')   

  6、多个装饰器的优先级

  @timmer

  @auth

  装饰器会优先执行最上面的,然后在执行以此类推,在定义节点从下往上定义,在执行阶段从上往下执行

应用

import time
def timmer(func):
def wrapper(*args,**kwargs):
print('====>timmer.wrapper')
start_time=time.time()
res=func(*args,**kwargs) #auth_wrapper
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return res
return wrapper login_user={'user':None,'status':False}
def auth(driver='file'):
def auth2(func):
def wrapper(*args,**kwargs):
print('=======>auth.wrapper')
time.sleep(5)
if driver == 'file':
if login_user['user'] and login_user['status']:
res=func(*args,**kwargs)
return res
else:
name=input('>>: ')
password=input('>>: ')
if name == 'egon' and password == '123':
login_user['user']='egon'
login_user['status']=True
print('\033[45mlogin successful\033[0m')
res=func(*args,**kwargs)
return res
else:
print('\033[45mlogin err\033[0m')
elif driver == 'ldap':
print('==========ldap的认证')
elif driver == 'mysql':
print('==========mysql的认证')
return func(*args,**kwargs)
else:
print('=========未知的认证来源')
return wrapper
return auth2
@auth('file') #index = auth2(time_warpper) --> auth2_warpper(time_warpper)
@timmer #index = timmer(index) ---> index = timmer_warpper
def index():
time.sleep(3)
print('welcome to index page') @auth(driver='mysql')
def home(name):
print('%s welcome to home page' % name) index() # auth2_warpper

  

  7、functools模块

  在装饰器的wrapper函数上@functools.wraps(func),用python自带的装饰器进行装饰,能将文档信息保留,而不调用装饰器的文档信息

def deco_1(func):
print ("enter into deco_1")
def wrapper(a,b):
print ("enter into deco_1_wrapper")
func(a,b) #传入的是deco_2的wrapper
print ("over deco_1")
return wrapper
def deco_2(func):
print ("enter into deco_2")
def wrapper(a,b):
print ("enter into deco_2_wrapper")
func(a,b)
print ("over deco_2")
return wrapper @deco_2 #addFunc = deco_2的wrapper
@deco_1 #addFunc = deco_1(addFunc()) == addFunc = deco_1(deco_2的wrapper)
def addFunc(a,b):
print ("result is %d" %(a+b))
addFunc(3,4) # addFunc = deco_1(deco_2的wrapper) '''
输出:
enter into deco_1
enter into deco_2
enter into deco_2_wrapper
enter into deco_1_wrapper
result is 7
over deco_1
over deco_2 '''

多个装饰器的执行顺序

六、迭代器

  1、基本概念

    重复+上一次迭代的结果为下一次迭代的初始值,重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值

#这不是迭代器,只满足重复,未满足上一次迭代的结果为下一次迭代的初始值
while True:
print('hello world')

   

#如下为迭代器,重复,上一次的迭代结果为下一次的迭代的初始值
l = [1, 2, 3]
count = 0
while count < len(l):
print('====>', l[count])
count += 1 l = (1, 2, 3)
count = 0
while count < len(l):
print('====>', l[count])
count += 1 s='hello'
count = 0
while count < len(s):
print('====>', s[count])
count += 1

   

  2、迭代器的用途

  对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式

  可迭代对象:含内置__iter__方法的都是可迭代对象

  

[1,2].__iter__()  #列表
'hello'.__iter__() #字符串
(1,2).__iter__() #元组
{'a':1,'b':2}.__iter__() #字典
{1,2,3}.__iter__() #集合

    

  迭代器:执行__iter__方法,得到的结果就是迭代器,迭代器对象有__next__方法

i=['a','b','c'].__iter__()  #从可迭代对象,变成迭代器

print(i)

print(i.__next__())
print(i.__next__())
print(i.__next__())
print(i.__next__()) #抛出异常:StopIteration  

  字典迭代的是key,可以通过dic[key]获取values

dic={'a':1,'b':2,'c':3}
i=dic.__iter__()
while True:
try:
key=i.__next__()
print(dic[key])
except StopIteration:
break  

  __iter__方法 == iter(),__next__方法 == next()

  3、判断一个对象是否为可迭代对象,而不是迭代器对象:

from collections import Iterable,Iterator

'abc'.__iter__()
().__iter__()
[].__iter__()
{'a':1}.__iter__()
{1,2}.__iter__() f=open('a.txt','w')
f.__iter__() #下列数据类型都是可迭代的对象
print(isinstance('abc',Iterable))
print(isinstance([],Iterable))
print(isinstance((),Iterable))
print(isinstance({'a':1},Iterable))
print(isinstance({1,2},Iterable))
print(isinstance(f,Iterable)) --
result
True
True
True
True
True
True
#只有文件是迭代器对象
# print(isinstance('abc',Iterator))
# print(isinstance([],Iterator))
# print(isinstance((),Iterator))
# print(isinstance({'a':1},Iterator))
# print(isinstance({1,2},Iterator))
# print(isinstance(f,Iterator)) --
result
False
False
False
False
False
True  

  4、总结:

    可迭代对象,只有__iter__方法,执行该方法得到迭代器

  迭代协议:

    对象有__next__方法

    对象有__iter__方法,对于迭代器对象来说,执行__iter__方法,得到的结果仍然是他本身

dic={'name':'dragon','age':18,'height':'180'}
print(dic.items())
i=iter(dic)
while True:
try:
k=next(i)
print(k)
except StopIteration:
break

  5、迭代器的优缺点:

  优点:

    1、提供了一种不依赖下标的迭代方式

    2、就迭代器本身来说,更节省内存

  缺点:

    1、无法获取迭代器对象的长度

    2、不如序列类型取值灵活,只是一次性的,只能往后取值,不能往前退

#enumerate是迭代器
l=[10000,2,3,4,5] i=enumerate(l) print(next(i))
print(next(i))

  

七、生成器(yield)

  1、定义

    只要函数体包含yield的关键字,该函数就是生成器函数

    生成器就是迭代器

例子:

  

#生成器,只要函数体含yield关键字,该函数就是生成器函数

def res():
print ('a')
yield 1
print ('b')
yield 2
print ('c')
yield 3
print ('d') g = res() for i in g:
print (i)

  2、yield功能

    1、相当于封装好的__iter__和__next__

    2、return只能返回一次值就终止,而yield能返回多值,每次都会将函数暂停,下一次next会从上一次暂停的位置继续执行

例子:tail -f access.log | grep 'python'

import time
def tail(filepath):
with open(filepath,encoding='utf-8') as f:
f.seek(0,2)
while True:
line=f.readline().strip()
if line:
yield line
else:
time.sleep(0.2) def grep(pattern,lines):
for line in lines:
if pattern in line:
yield line g=grep('python',tail('a.txt')) #在grep里添加yield又变成一个生成器,需要g=grep进行调用生成器
print(g) for i in g: #for 循环 触发grep生成器执行,grep 生成器会触发for循环,触发上一个tail生成器的执行
print(i)

  

八、内置函数

  

abs 求绝对值

all(),括号内放可迭代对象, bool值运算,所有为true才为true,可迭代值为空也为true

any() bool值运算,有一个为真则为真,可迭代对象为空返回false

bin() 把10进制转二进制

hex()

#判断是否为可调用对象
callable()
#按照ascii码,将字符对应位置
chr(68)
ord
#complex 复数
complex(1+2j)
print (res.real)
print (res.imag) #工厂函数 list
str
dict
set
int #dir 查看一个对象的属性
l = []
print (l) #divmod 可以完成分页功能 print (divmod(10,3)) #eval 将字符串转
dic = {'a':1,'b':2}
d = eval(dict)
print (type(d),d['a'])
#frozenset({1,2}) 定义不可变集合 #hash 得到哈希值
print (hash('adadsd')) #id is 身份运算符 #pow x**y %z reversed #反转 为迭代器 round #保留几位小数 slice 切片 可以重复利用 lis = ['a','b','c']
print (lis[1:3:2]) l = slice(1,4,2)
print (l[s]) #切片方式可以在任意位置去调用 vars() 不加参数和locals() zip #拉链函数 s = hello
lis = [1,2,3,4,5] z = zip(s,lis) __import__ __import__('time')
#以字符串的形式倒入模块

  

  

   

    

  

python自动化开发-[第四天]-函数的更多相关文章

  1. python自动化开发学习 进程, 线程, 协程

    python自动化开发学习 进程, 线程, 协程   前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...

  2. python自动化开发学习 I/O多路复用

    python自动化开发学习 I/O多路复用   一. 简介 socketserver在内部是由I/O多路复用,多线程和多进程,实现了并发通信.IO多路复用的系统消耗很小. IO多路复用底层就是监听so ...

  3. python自动化开发-[第三天]-编码,函数,文件操作

    今日概要 - 编码详解 - 文件操作 - 初识函数 一.字符编码 1.代码执行过程 代码-->解释器翻译-->机器码-->执行 2.ASCII ASCII:一个Bytes代表一个字符 ...

  4. python自动化开发-[第九天]-异常处理、进程

    今日概要: 1.异常处理使用 2.进程 3.paramiko模块使用 一.异常处理 1.常见的错误异常 #错误异常一 print(a) #NameError #错误异常二 int('sdadsds') ...

  5. python自动化开发-[第七天]-面向对象

    今日概要: 1.继承 2.封装 3.多态与多态性 4.反射 5.绑定方法和非绑定方法 一.新式类和经典类的区别 大前提: 1.只有在python2中才分新式类和经典类,python3中统一都是新式类 ...

  6. Python学习系列----第四章 函数

    4.1 函数定义   函数是python中重要的工具.函数用关键字 def 来定义.def 关键字后跟一个函数的标识符名称,然后跟一对圆括号.圆括号之中可以包括一些变量名,该行以冒号结尾.接下来是一块 ...

  7. python自动化开发-[第二十四天]-高性能相关与初识scrapy

    今日内容概要 1.高性能相关 2.scrapy初识 上节回顾: 1. Http协议 Http协议:GET / http1.1/r/n...../r/r/r/na=1 TCP协议:sendall(&qu ...

  8. python自动化开发-[第十四天]-javascript(续)

    今日概要: 1.数据类型 2.函数function 3.BOM 4.DOM 1.运算符 算术运算符: + - * / % ++ -- 比较运算符: > >= < <= != = ...

  9. Python自动化开发 - 内置函数总结

    Python解释器提供了很多内置函数 参考链接:https://docs.python.org/3.6/library/functions.html 一.数学相关 1.绝对值:abs(-1) 2.最大 ...

随机推荐

  1. zabbix在执行docker命令是报错

    系统环境 ubuntu 14.04  x64 安装了zabbix,去监控docker的状态,安装zabbix见我的另外一篇文章 错误如下 WARNING: Error loading config f ...

  2. 二:C#对象、集合、DataTable与Json内容互转示例;

    导航目录: Newtonsoft.Json 概述 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型:    二:C#对象.集合.DataTable与Json内容互转示例: ...

  3. 进程PID 与PPID

    # 同一个程序执行多次是多个进程 import time import os print('爹是:',os.getppid()) #查看父进程 print('me是: ',os.getpid()) # ...

  4. Python里format()方法基本使用

    '''第一种:自然连接''' #format 连接字符串 str = '{}使用的python是{}版本'.format('我','3.6.5') print(str) #打印结果:我使用的pytho ...

  5. 慢腾腾的Quartus prime16.0加快编译速度

    前言 当一个工程反复修改的时候,可能有时候源代码没有更改,为了加快编译速度可以配置quartus一些选项.当然,初次编译的速度是否会提升,未验证.更高级的设计分区以及逻辑锁区提升速度,以后阐述. 流程 ...

  6. 【BZOJ1211】【HNOI2004】树的计数 prufer序列

    题目描述 给你\(n\)和\(n\)个点的度数,问你有多少个满足度数要求的生成树. 无解输出\(0\).保证答案不超过\({10}^{17}\). \(n\leq 150\) 题解 考虑prufer序 ...

  7. 【CF472G】Design Tutorial 压位

    题目大意 给出两个\(01\)序列\(A\)和\(B\) 汉明距离定义为两个长度相同的序列中,有多少个对应位置上的数字不一样 \(00111\) 和 \(10101\)的距离为\(2\) \(Q\)次 ...

  8. flask简单登录注册

    效果图 发布问答页面需要登录才能访问,没有登录会跳转到登录页面 模板继承,正则验证,数据库迁移,md5加密 mysql 5.7 登录页面 登录后的发布问答页面,右上角会显示用户名和注销 项目代码:码云

  9. MT【267】第一次很重要

    \begin{equation*}\textbf{已知}x_1,x_2<\pi,x_{n+1}=x_n+\left\{ \begin{aligned} sin x_n &,x_n> ...

  10. windows 设置ipsec防火墙

    windows server 推荐使用ipsec修改防火墙设置,默认防火墙需要手动导入导出.wfw文件,需要手动添加单条规则,维护麻烦,推荐关闭,使用ipsec管理 以下是线上防火墙配置,可参照业务环 ...