1. 程式人生 > >python學習之函數學習進階

python學習之函數學習進階

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學習之函數學習進階