python探测_python之函数深入探测

第一:命名空间与作用域

命名空间:

局部命名空间:

def foo():

x=1

def func():

pass

全局命名空间:

import time

class ClassName:pass

def foo():pass

内键命名空间:

sum,max,min 等

python加载三个命名空间的顺序:

1.内键命名空间

2.全局命名空间:文件级别的或叫做模块级别的

3.局部命名空间:只有调用函数的时候才会加载,函数调用结束就被释放掉

作用域:

全局作用域:

同时x=1为全局变量

x=1

deffunc1():deffunc2():deffunc3():print(x)

func3()

func2()

func1()

输出结果1

局部作用域:

x=1

deffunc1():deffunc2():deffunc3():

x=100

print(x)

func3()

func2()

func1()

输出结果:100

第二:闭包

闭包:本质就是一个内部函数

特点:这个内部函数必须包含对外部函数作用域(非全局作用)名字的引用

示例:

deff1():

x=1y=2

deff2():print(x)print(y)returnf2

func=f1()#func()

print(func.__closure__[0].cell_contents)#查看闭包函数的方法

print(func.__closure__[1].cell_contents)#f2为闭包函数

输出结果:1

2

惰性计算:啥时候用啥时候调用

from urllib.request importurlopendefpage(url):defget():returnurlopen(url).read()returnget

baidu=page('http://www.baidu.com')

python=page('http://www.python.org')print(baidu)print(python)

输出结果:.get at 0x0000000002DE6BF8>

.get at 0x0000000002DE6C80>函数没有执行,已经传了一个参数

第三:装饰器

开放封闭原则

装饰器需要遵循的原则:1,不改变被修饰对象的源代码;2,不改变被修饰对象的调用方式

装饰器是在遵守1和2的前提下,为被装饰的对象添加新功能

装饰器无参基本框架:

#这就是一个实现一个装饰器最基本的架子

deftimer(func):defwrapper():

func()return wrapper

装饰器有参基本框架:

deftimer(func):def wrapper(*args,**kwargs):

func(*args,**kwargs)return wrapper

无参装饰器:

importtimedef timer(func): #func=最原始的index

defwarpper():

start_time=time.time()

func()

end_time=time.time()print('run time is %s' % (end_time -start_time))returnwarpper#无参装饰器

@timer #index=timer(index) 此时的index就是warpper

defindex():

time.sleep(1)print("welcome to index")

index()#就是在调用warpper()

原来的index的函数只会输出welcome to index

加上装饰器后;

输出内容为:

welcome to index

run timeis 1.0060575008392334

有参数装饰器:

importtimedef timer(func): #func=最原始的index

defwarpper(user):

start_time=time.time()

func(user)

end_time=time.time()print('run time is %s' % (end_time -start_time))returnwarpper

@timer#index=timer(index) 此时的index就是warpper

defhome(user):

time.sleep(1)print("home %s"%user)

home('cy')#就是在调用warpper()

输出结果:

home cy

run timeis 1.0000574588775635

如果传入的参数是关键字类型或者其他的

importtimedef timer(func): #func=最原始的index

def warpper(*args,**kwargs):

start_time=time.time()

func(*args,**kwargs)

end_time=time.time()print('run time is %s' % (end_time -start_time))returnwarpper

@timer#index=timer(index) 此时的index就是warpper

defhome(user):

time.sleep(1)print("home %s"%user)

home('cy')#就是在调用warpper()

home(user="zzl")#输出结果:

home cy

run timeis 1.0000574588775635home zzl

run timeis 1.0000569820404053

如果原函数有返回值:

importtimedef timer(func): #func=最原始的index

def warpper(*args,**kwargs):

start_time=time.time()

res=func(*args,**kwargs)

end_time=time.time()print('run time is %s' % (end_time -start_time))returnresreturnwarpper

@timer#index=timer(index) 此时的index就是warpper

defhome(user):

time.sleep(1)return user + 'is student'res=home('cy')#就是在调用warpper()

print(res)#输出结果:

run time is 1.0000574588775635cyis student

装饰器的应用:

无参装饰器的应用:

user_info

name:zzl,passwd:123name:cyy,passwd:123name:cy,passwd:123name:zl,passwd:123

code:

defuser_info():

file= open('user_info')

data=file.readlines()

list_info=[]for i indata:

lis=[i.strip()]for s inlis:

result= [ele.strip() for ele in s.split(",")]

dict_info={}for x inresult:

res= [ele.strip() for ele in x.split(':')]

dict_info.update(dict([res]))

list_info.append(dict_info)returnlist_info

user_list=user_info()defhelp():print(user_list)

current_user={'username':None,'login':False}defauth_deco(func):def wrapper(*args,**kwargs):if current_user['username'] and current_user['login']:

res=func(*args,**kwargs)returnres

username=input('用户名:').strip()

passwd=input('密码:').strip()for index,user_dic inenumerate(user_list):if username == user_dic['name'] and passwd == user_dic['passwd']:

current_user['username']=username

current_user['login']=True

res=func(*args,**kwargs)returnresbreak

else:print('用户名或者密码错误,重新登录')returnwrapper

help()#无参函数

@auth_decodefhome():print('这里是你家')

home()

有参装饰器的应用:

user_info

name:zzl,passwd:123name:cyy,passwd:123name:cy,passwd:123name:zl,passwd:123

code:

defuser_info():

file= open('user_info')

data=file.readlines()

list_info=[]for i indata:

lis=[i.strip()]for s inlis:

result= [ele.strip() for ele in s.split(",")]

dict_info={}for x inresult:

res= [ele.strip() for ele in x.split(':')]

dict_info.update(dict([res]))

list_info.append(dict_info)returnlist_info

user_list=user_info()defhelp():print(user_list)

current_user={'username':None,'login':False}def auth(auth_type='file'):defauth_deco(func):def wrapper(*args,**kwargs):if auth_type == 'file':if current_user['username'] and current_user['login']:

res=func(*args,**kwargs)returnres

username=input('用户名:').strip()

passwd=input('密码:').strip()for index,user_dic inenumerate(user_list):if username == user_dic['name'] and passwd == user_dic['passwd']:

current_user['username']=username

current_user['login']=True

res=func(*args,**kwargs)returnresbreak

else:print('用户名或者密码错误,重新登录')elif auth_type == 'ldap':print('我是ldap')

res=func(*args,**kwargs)returnresreturnwrapperreturnauth_deco#auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')#就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数

@auth(auth_type='ldap')defindex():print('欢迎来到主页面')

@auth(auth_type='file')defhome():print('到家了')

index()print(user_list)

home()

第四:迭代器

#迭代:更新换代 描述的是一个重复的过程 for while

lis=[4,5,6]

i=0while i

i+=1

for i inrange(len(lis)):print(lis[i])#输出结果:

4

5

6

4

5

6

针对没有下标的数据类型,我们在想迭代他们的话,就必须提供一种不按照下标取值的方式,python针对这种情况,已经为很多很多的数据类型内置了一个__iter__的方法。

d={'a':1,'b':2}print(d.__iter__())print([].__iter__())#输出结果:

数据类型凡是有__iter__方法的都是可迭代的iterable,执行这个方法得到结果就是迭代器iterator,凡是iterator都内置一个__next__方法

d={'a':1,'b':2}

i=d.__iter__()print(i)print(i.__next__())print(i.__next__())print(i.__next__())

输出结果:a

bprint(i.__next__())

StopIteration #这个不是报错是字典没有值了

迭代的认识(针对列表)

l=[1,2,3,4,5]

i=iter(l)whilel:try:print(next(i)) #i.__next__()

exceptStopIteration as e:break

for i in l:#l.__iter__()

print(i)#输出结果:

1

2

3

4

5

1

2

3

4

5

迭代器牛逼之处:针对没有下边的数据类型:(字典,文件等)

字典:

dic={'a':1,'b':2,'c':3}

d=iter(dic)whiled:try:print(dic[next(d)])exceptStopIteration:break

for i indic:print(dic[i])#输出结果:

1

2

3

1

2

3

文件:

f=open('text','r')print(f)for i in f: #i=f.__iter__()

print(i)

输出结果:<_io.textiowrapper name="text" mode="r" encoding="cp936">zzl

cyy

for,while之所以能够循环字典,文件,是因为内置用了迭代器的方法

迭代器的优点:

1.提供了一种统一的迭代方式

2.惰性计算,省内存

迭代器的缺点:

1.迭代器看起来就像是一个序列,但是你永远无法预知迭代器的长度

2.不能倒着走,而且是一次性的,只能走一遍

迭代器(Iterator),可迭代的(Iterable)

from collections importIterator,Iterableprint(isinstance('zzl',Iterable))print(isinstance({},Iterable))print(isinstance((),Iterable))print(isinstance({}.__iter__(),Iterator))

f=open('text','r')print(isinstance(f,Iterator))print(isinstance(f,Iterable))

输出结果:

True

True

True

True

True

True

第五:生成器

#凡是在函数内部有关键字yield,那么这个函数就是一个生成器。 特别指数在于:函数名+()不再执行,而是得到一个生成器。

from collections importIteratordeffoo():print('我是老大')yield 1

print('我是老二')yield 2

print('我是老三')yield 3

print('我是老四')yield 4

print('我是老五')yield 5

print('我是老六')yield 6g=foo() #调用以后把它当成迭代器来看

print(g)print(isinstance(g,Iterator))print(next(g))print(next(g))print(next(g))print(next(g))print(next(g))print(next(g))print(next(g))

输出结果:True

我是老大1我是老二2我是老三3我是老四4我是老五5我是老六6File"D:/my/python script/untitled/生成器.py", line 30, in

print(next(g))

StopIteration#这不是报错,而是没有值了,怎么解决呢,请往下看

deffoo():print('我是老大')yield 1

print('我是老二')yield 2

print('我是老三')yield 3

print('我是老四')yield 4

print('我是老五')yield 5

print('我是老六')yield 6g=foo() #调用以后把它当成迭代器来看

for i in g: #i=next(g)

print(i)

输出结果:

我是老大1我是老二2我是老三3我是老四4我是老五5我是老六6

总结:yield的功能是什么?

1.yield是为函数定制__iter__和__next__方法,就是提供一种自定义迭代器的优雅的方法

2.就相当于return,但是可以返回多次

3.生成器本质就是一个数据流,next(生成器)才触发生成器函数的一次执行,下一次next会从上一次暂停的位置继续执行,直到重新遇到一个新的yield。

实现tail -f one.txt |  grep ‘cy’的功能:

importtimedeftail(file_path):

with open(file_path) as f:

f.seek(0,2)whileTrue:

line=f.readline()if notline:

time.sleep(0.1)else:yieldlinedefgrep(lines,pattern):for line inlines:if pattern inline:yieldline

pattern_line=grep(tail(r'C:/one.txt'),'cy')for i inpattern_line:print(i)

输出结果:

cyy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值