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
def func1():
    def func2():
        def func3():
            print(x)
        func3()
    func2()
func1()

输出结果
1

局部作用域:

x=1
def func1():
    def func2():
        def func3():
            x=100
            print(x)
        func3()
    func2()
func1()


输出结果:
100

第二:闭包

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

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

示例:

def f1():
    x=1
    y=2
    def f2():
        print(x)
        print(y)
    return f2

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

#f2为闭包函数

输出结果:
1
2

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

from urllib.request import urlopen

def page(url): 
    def get():
        return urlopen(url).read()
    return get

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

print(baidu)
print(python)

输出结果:
<function page.<locals>.get at 0x0000000002DE6BF8>
<function page.<locals>.get at 0x0000000002DE6C80>

函数没有执行,已经传了一个参数

第三:装饰器

开放封闭原则

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

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

装饰器无参基本框架:
#这就是一个实现一个装饰器最基本的架子
def timer(func):
    def wrapper():
        func()
    return wrapper

装饰器有参基本框架:

def timer(func):
    def wrapper(*args,**kwargs):
         func(*args,**kwargs)
    return wrapper

无参装饰器:

import time
def timer(func): #func=最原始的index
    def warpper():
        start_time=time.time()
        func()
        end_time=time.time()
        print('run time is %s' % (end_time - start_time))
    return warpper

#无参装饰器
@timer #index=timer(index) 此时的index就是warpper
def index():
    time.sleep(1)
    print("welcome to index")

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

原来的index的函数只会输出welcome to index
加上装饰器后;
输出内容为:
welcome to index
run time is 1.0060575008392334

有参数装饰器:

import time
def timer(func): #func=最原始的index
    def warpper(user):
        start_time=time.time()
        func(user)
        end_time=time.time()
        print('run time is %s' % (end_time - start_time))
    return warpper

@timer #index=timer(index) 此时的index就是warpper
def home(user):
    time.sleep(1)
    print("home %s"% user)

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

输出结果:
home cy
run time is 1.0000574588775635

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

import time
def 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))
    return warpper

@timer #index=timer(index) 此时的index就是warpper
def home(user):
    time.sleep(1)
    print("home %s"% user)

home('cy')#就是在调用warpper()
home(user="zzl")
#输出结果:
home cy
run time is 1.0000574588775635
home zzl
run time is 1.0000569820404053

如果原函数有返回值:

import time
def 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))
        return res
    return warpper

@timer #index=timer(index) 此时的index就是warpper
def home(user):
    time.sleep(1)
    return user + ' is student'

res=home('cy')#就是在调用warpper()
print(res)
#输出结果:
run time is 1.0000574588775635
cy is student

装饰器的应用:

无参装饰器的应用:

user_info

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

code:

def user_info():
    file = open('user_info')
    data=file.readlines()
    list_info=[]
    for i in data:
        lis=[i.strip()]
        for s in lis:
            result = [ele.strip() for ele in s.split(",")]
            dict_info={}
            for x in result:
                res = [ele.strip() for ele in x.split(':')]
                dict_info.update(dict([res]))
            list_info.append(dict_info)
    return list_info

user_list=user_info()

def help():
    print(user_list)

current_user={'username':None,'login':False}

def auth_deco(func):
    def wrapper(*args,**kwargs):
        if current_user['username'] and current_user['login']:
            res=func(*args,**kwargs)
            return res
        username=input('用户名: ').strip()
        passwd=input('密码: ').strip()
        for index,user_dic in enumerate(user_list):
            if username == user_dic['name'] and passwd == user_dic['passwd']:
                current_user['username']=username

                current_user['login']=True
                res=func(*args,**kwargs)
                return res
                break
        else:
            print('用户名或者密码错误,重新登录')

    return wrapper

help()

#无参函数
@auth_deco
def home():
    print('这里是你家')
home()

有参装饰器的应用:

user_info

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

code:

def user_info():
    file = open('user_info')
    data=file.readlines()
    list_info=[]
    for i in data:
        lis=[i.strip()]
        for s in lis:
            result = [ele.strip() for ele in s.split(",")]
            dict_info={}
            for x in result:
                res = [ele.strip() for ele in x.split(':')]
                dict_info.update(dict([res]))
            list_info.append(dict_info)
    return list_info

user_list=user_info()

def help():
    print(user_list)

current_user={'username':None,'login':False}
def auth(auth_type='file'):
    def auth_deco(func):
        def wrapper(*args,**kwargs):
            if auth_type == 'file':
                if current_user['username'] and current_user['login']:
                    res=func(*args,**kwargs)
                    return res
                username=input('用户名: ').strip()
                passwd=input('密码: ').strip()

                for index,user_dic in enumerate(user_list):
                    if username == user_dic['name'] and passwd == user_dic['passwd']:
                        current_user['username']=username
                        current_user['login']=True
                        res=func(*args,**kwargs)
                        return res
                        break
                else:
                    print('用户名或者密码错误,重新登录')
            elif auth_type == 'ldap':
                print('我是ldap')
                res=func(*args,**kwargs)
                return res
        return wrapper
    return auth_deco


#auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file')
#就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数
@auth(auth_type='ldap')
def index():
    print('欢迎来到主页面')

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

index()

print(user_list)
home()

第四:迭代器

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

lis=[4,5,6]
i=0
while i<len(lis):
    print(lis[i])
    i+=1

for i in range(len(lis)):
    print(lis[i])

#输出结果:
4
5
6
4
5
6

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

d={'a':1,'b':2}
print(d.__iter__())
print([].__iter__())
#输出结果:
<dict_keyiterator object at 0x000000000214B728>
<list_iterator object at 0x0000000002859400>

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

d={'a':1,'b':2}
i=d.__iter__()
print(i)
print(i.__next__())
print(i.__next__())
print(i.__next__())

输出结果:
<dict_keyiterator object at 0x000000000220B778>
a
b
    print(i.__next__())
StopIteration               #这个不是报错是字典没有值了

 迭代的认识(针对列表)

l=[1,2,3,4,5]
i=iter(l)
while l:
    try:
        print(next(i)) #i.__next__()
    except StopIteration 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)
while d:
    try:
        print(dic[next(d)])
    except StopIteration:
        break

for i in dic:
    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 import Iterator,Iterable
print(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 import Iterator
def foo():
    print('我是老大')
    yield 1
    print('我是老二')
    yield 2
    print('我是老三')
    yield 3
    print('我是老四')
    yield 4
    print('我是老五')
    yield 5
    print('我是老六')
    yield 6

g=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))

输出结果:
<generator object foo at 0x0000000002160620>
True
我是老大
1
我是老二
2
我是老三
3
我是老四
4
我是老五
5
我是老六
6

 File "D:/my/python script/untitled/生成器.py", line 30, in <module>
    print(next(g))
StopIteration  #这不是报错,而是没有值了,怎么解决呢,请往下看
def foo():
    print('我是老大')
    yield 1
    print('我是老二')
    yield 2
    print('我是老三')
    yield 3
    print('我是老四')
    yield 4
    print('我是老五')
    yield 5
    print('我是老六')
    yield 6

g=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’的功能:

import time
def tail(file_path):
    with open(file_path) as f:
        f.seek(0,2)
        while True:
            line=f.readline()
            if not line:
                time.sleep(0.1)
            else:
                yield line

def grep(lines,pattern):
    for line in lines:
        if pattern in line:
            yield line

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

输出结果:
cyy
原文地址:https://www.cnblogs.com/ylqh/p/6417698.html