python学习之函数学习进阶

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python学习之函数学习进阶相关的知识,希望对你有一定的参考价值。

1.名称空间

python有三种名称空间
内置名称空间: 随着python解释器的启动而产生
print(sum)
print(max)

全局名称空间: 文件的执行会产生全局名称空间,指的是文件级别的定义名字都会放入该空间
x = 11
if x == 11:
    print(x)

局部名称空间: 调用函数时会产生局部名称空间,只在函数调用时临时绑定,调用结束时解绑
x = 1000
def foo():
    x = 1
    print(x)
foo()
print(x)

作用域:
    1.全局作用域: 内置名称空间,全局名称空间,全局有效,在任何位置都能被访问到,
    除非del删除,否则存活到文件结束。
    2.局部作用域: 局部名称空间,局部有效,只能在局部范围调用,调用结束失效。

名字的查找顺序: 局部名称空间-->全局名称空间-->内置名称空间
x = 1000
def func():
    x = 2
    print(locals())    #locals()查看局部作用域内的名字
print(globals())    #globals()查看全局作用域内的名字


2.函数对象
    1.可以被引用
    2.可以当作参数传递
    3.返回值可以是函数
    4.可以当作容器类型的元素
    
 例子:
     def foo():
         print("from foo")
     func = foo
     print(foo)
     print(func)
     foo()
     func()
     
     def foo():
         print("from foo")
     def bar(func):
         print(func)
         func()
     bar(foo)
     
     def foo():
         print("from foo")
     dic = {‘func‘: foo}
     print(dic[‘func‘])
     dic[‘func‘]()
     
     
     
3.闭包函数
    闭包:
      1.定义在内部函数
      2.包含对外部作用域而非全局作用域的引用
  该内部函数就称作闭包函数
  例子:
  def f1():
    x = 1
    def f2():     #f2称作闭包函数
      print(x)
    return f2
  f = f1()
  print(f)   #打印f2函数的内存地址
  f()    #打印1
 
   例子:
   from urllib.request import urlopen
   def index(url):
       def get():
           return urlopen(url).read()
       return get
   oldboy = index(‘http://www.baidu.com‘)
   print(oldboy().decode(‘utf-8‘))
   print(oldboy.__closure__[0].cell_contents)    #打印外部引用而非全局引用对象
   
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 {0}".format(stop_time - start_time))
        return wrapper
        
    @timmer        #相当于index = timmer(index)
    def index():
        time.sleep(3)
        print("welcome to index")
        return 1
        
    index()    #其实相当于执行了timmer(index)
    
    例子:
    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 {0}".format(stop_time - start_time))
        return wrapper
        
    def index():
        time.sleep(3)
        print("welcome to index")
    
    f = timmer(index)
    print(f)
    f()        #f()<=====>wrapper()
    
    
    认证用户登录
    login_user = {‘user‘: None, ‘status‘: False}
    def auth(func):
        def wrapper(*args, **kwargs):
            if login_user[‘user‘] and login_user[‘status‘]:
                res = func(*args, **kwargs)
                return res
            else:
                name = input("请输入姓名:")
                passwd = input("请输入密码:")
                if name == "hyh" and passwd == "123":
                    login_user[‘user‘] = "hyh"
                    login_user[‘status‘] = True
                    print("\033[45mlogin successful\033[0m")
                    res = func(*args, **kwargs)
                    return res
                else:
                    print("\033[45mlogin err\033[0m")
        return wrapper
        
   @auth
   def index():
       print("welcome to index page")
       
   @auth
   def home(name):
       print("%s welcome to home page" % (name)) 
       
   index()
   home("hyh")
   
5.迭代器
    迭代器的概念: 重复上一次迭代的结果为下一次迭代的初始值,重复的过程称为迭代,
    每次重复即一次迭代
    
    为什么要有迭代器?
    对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式
    
    可迭代对象: 内置__iter__方法的都是可迭代对象
    [1,2].__iter__()
    ‘hello‘.__iter__()
    (1,2).__iter__()
    {"a":1, "b": 2}.__iter__()
    {1,2,3}.__iter__()
    
    迭代器: 执行__iter__()方法,得到的结果就是迭代器,迭代器有__next__()方法
    i = [1,2,3].__iter__()
    print(i.__next__())        #打印1
    print(i.__next__())        #打印2
    print(i.__next__())        #打印3
    print(i.__next__())    #抛出异常
    
    i__iter__() <==>iter(i)
    i__next__() <==>next(i)
    
    如何判断一个对象是可迭代对象,还是迭代器对象
    from collections import Iterable, Iterator
    print(isinstance(‘abc‘,Iterable))
    print(isinstance([],Iterable))
    print(isinstance((),Iterable))
    print(isinstance({‘a‘:1},Iterable))
    print(isinstance({1,2},Iterable))
    f=open(‘a.txt‘,‘w‘)
    f.__iter__()
    print(isinstance(f,Iterable))    #只有文件是迭代器对象
    
    可迭代对象:只有__iter__方法,执行该方法得到的迭代器对象
    迭代协议:
        对象有__next__
        对象有__iter__,对于迭代器对象来说,执行__iter__方法,得到的结果仍然是它本身
        
    迭代器的优点和缺点
        优点:
            1.提供了一种不依赖下标的迭代方式
            2.就跌迭代器本身来说,更节省内存

        缺点:
            1. 无法获取迭代器对象的长度
            2. 不如序列类型取值灵活,是一次性的,只能往后取值,不能往前退

本文出自 “linux技术” 博客,请务必保留此出处http://xiaojishu.blog.51cto.com/4278020/1928374

以上是关于python学习之函数学习进阶的主要内容,如果未能解决你的问题,请参考以下文章

python学习之函数学习进阶

Python学习之函数进阶

python学习之函数进阶三

第二模块:03python学习之函数进阶

Python学习之装饰器进阶

python学习之面向对象学习进阶