日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

[学习总结] python语言学习总结 (三)

發布時間:2025/3/15 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [学习总结] python语言学习总结 (三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

函數閉包

定義

延伸了作用域的函數(能訪問定義體之外定義的非全局變量

作用

  • 共享變量的時候避免使用了不安全的全局變量
  • 允許將函數與某些數據關聯起來,類似于簡化版面向對象編程
  • 相同代碼每次生成的閉包,其延伸的作用域都彼此獨立(計數器,注冊表)
  • 函數的一部分行為在編寫時無法預知,需要動態實現,同時又想保持接口一致性
  • 較低的內存開銷:類的生命周期遠大于閉包
  • 實現裝飾器
  • 代碼

    print("Class方式:") class Averager:def __init__(self):self.series = []def __call__(self,new_val):self.series.append(new_val)return sum(self.series)/len(self.series) avg1 = Averager() print(avg1(3)) print(avg1(2))print("閉包方式:") def Avg_1():count = 0total = 0def Avg_2(val):nonlocal total,counttotal+=valcount+=1return total/countreturn Avg_2 avg = Avg_1() print(avg(9)) print(avg(10)) ''' 輸出 Class方式: 3.0 2.5 閉包方式: 9.0 9.5 '''

    理解

    功能說明

    這段代碼需要解決的是,定義一個average函數,我們每次傳進去一個值,都可以得到這個值和之前傳入值的平均值。比如第一次傳入1,均值就是1,第二次傳入2,均值就是1.5,以此類推。

    類方式

    第一種方式是通過構建一個類,這也是我們通常容易想到的方式,利用在類里面創建一個list,每次調用都將新值append進去,這是一種解決方法。

    函數閉包方式

    這里跟前面提到的作用域是有關的,函數閉包延伸了作用域,我們可以看到,我們的外層函數只是為了存儲兩個變量而已,沒有其他作用了。其實這時候應該有個疑惑,在調用Avg_1()之后,由于count和total是在Loval層,函數調用結束了應該銷毀了才是,但實際上并沒有,我們在Avg_2中通過nolocal關鍵字延長了兩個變量的生命周期,使得我們在每次調用的時候都能訪問都兩個變量,達到效果。

    裝飾器

    為什么會出現裝飾器這個東西

    • 名稱管理
    • 顯示調用
    • 就近原則
    • 充分復用

    @語法糖

    '@' 用做函數的修飾符,可以在模塊或者類的定義層內對函數進行修飾,出現在函數定義的前一行,不允許和函數定義在同一行。

    什么是裝飾器

    • 裝飾器是一個可調用的對象,以某種方式增強函數的功能
    • 裝飾器是一個語法糖,在源碼中標記函數(此源碼指編譯后的源碼)
    • 解釋器解析源碼的時候將被裝飾的函數作為第一個位置參數傳給裝飾器
    • 裝飾器可能會直接處理被裝飾函數,然后返回它(一般僅修改屬性,不修改代碼)
    • 裝飾器也可能用一個新的函數或可調用對象替換被裝飾函數(但核心功能一般不變)
    • 裝飾器僅僅看著像閉包,其實功能的定位與閉包有重合也有很大區別
    • 裝飾器模式的本質是元編程:在運行時改變程序行為
    • 裝飾器的一個不可忽視的特性:在模塊加載時立即執行
    • 裝飾器是可以堆疊的,自底向上逐個裝飾
    • 裝飾器是可以帶參數的,但此時至少要寫兩個裝飾器
    • 裝飾器的更加Pythonic的實現方式其實是在類中實現 call() 方法

    代碼

    def check_param(**kw):flag = kw.get('flag')def check_p(func):def decorate(*args):if flag:if not all([isinstance(arg,int) for arg in args]):raise TypeError("{} only accepts integers as argument".format(func.__name__))return func(*args)return decoratereturn check_p@check_param(flag=True) def my_sum(a,b):return a+bif __name__=='__main__':print(my_sum(1,2))print(my_sum(1,2.0))''' 輸出 3 Traceback (most recent call last):File "/home/xueaoru/文檔/pydemo/blog.py", line 18, in <module>print(my_sum(1,2.0))File "/home/xueaoru/文檔/pydemo/blog.py", line 7, in decorateraise TypeError("{} only accepts integers as argument".format(func.__name__)) TypeError: my_sum only accepts integers as argument'''

    解釋

    上面的代碼是為了完成一個檢查my_sum函數的參數是否是整數的功能的裝飾器,同時增加了開關功能,我們將flag設置為true就是開啟檢查功能,如果不是整數,則直接報錯。

    理解

    裝飾器是對函數在不改變原有函數內部實現的情況下,對原有函數進行功能增強。而@語法糖是對原函數進行修飾的修飾符,當調用@語法糖進行修飾的時候,即使該函數并不調用,也會執行修飾語句,因為觸發了運行裝飾器。這時候該函數作為參數傳給修飾函數的外部函數,然后該函數作為引用賦值給內部函數的函數名,也就是說我們真正的操作是在內部函數中進行的,因此可以在內部函數中對原函數進行功能增強。其中,有參數的時候呢,內部函數也需要通過*和**拆包得到參數,原函數有返回值的時候呢,我們在調用完原函數的時候也應該給出返回值。而裝飾器本身帶參數的時候呢,可以在裝飾函數外再加一層接收參數的包裝得到參數。

    OOP In Python

    概念

    一切都是對象

    從語言設計層面理解Python中的數據類型:一切都是對象,都是從Object繼承過來的。Object由三部分組成:identity、type、value。

    identity

    理解

    當Objects創建之后呢,identity也不會改變,直到被銷毀。我覺得跟c++里的地址差不多吧,當然也不能完全這么理解,也有不同的方。

    要點

    • 變量存儲的是創建的Object的identity
    • 創建出來的不同Object有不同的identity
    • 變量的id變了不是因為Object的identity變了,而是對應的Object變了
    • 對于不可變對象而言,計算結果如果已經存在,可以直接返回相同的identity

    type

    要點

    • 當Object創建后,其type不會改變
    • type決定了一個Object可以支持那些運算,可能的值在哪些范圍

    value

    要點

    • 有些Object的value可以改變:可變對象
    • 有些Object的value不可以改變:不可變對象

    每一個class在定義的時候如果沒有繼承的話,那么他繼承的就是Object這個超級class,而每一個自定義的class在python中都是一個type object。

    @classmethod

    理解

    可以把類中的某個方法變成這個類的方法而不依賴于對象,也就是說,在對象沒有創建的時候,我們也可以調用這個類的方法執行一定的操作。這就有點像C++中的靜態成員函數。

    代碼

    class Student:teacher_name = "Omg"def __init__(self,name):self._name = name@classmethoddef Teacher(cls):print(cls.teacher_name)def Me(self):print(self._name) if __name__== '__main__':aa = Student("xue")aa.Teacher()aa.Me()Student.Teacher() ''' Omg xue Omg '''

    解釋

    這段代碼是通過調用Teacher方法得到老師的名字,可以看出,我們就算不通過對象直接調用,也可以輸出老師的名字。classmethod就起這個作用。

    @property

    理解

    本質上這是一個裝飾器,可以省去寫get、set函數的對外綁定。

    property

    函數原型為

    property(fget=None, fset=None, fdel=None, doc=None)

    代碼

    @property與下面的代碼效果是一樣的

    class Teacher:def __init__(self,name,subject):self._name = nameself._subject = subjectdef setName(self,name):self._name = namedef getName(self):return self._namedef setSubject(self,subject):self._subject = subjectdef getSubject(self):return self._subjectdef show(self):print("name is:{} and subject is:{}".format(self._name,self._subject))name = property(getName,setName)subject = property(getSubject,setSubject) if __name__ == '__main__':t = Teacher("A","math")t.show()t.name = "B"t.subject = "English"t.show() ''' name is:A and subject is:math name is:B and subject is:English '''

    使用@property之后的更加優美的版本

    class Teacher:def __init__(self,name,subject):self._name = nameself._subject = subject@propertydef name(self):return self._name@name.setterdef name(self,name):self._name = name@propertydef subject(self):return self._subject@subject.setterdef subject(self,subject):self._subject = subjectdef show(self):print("name is:{} and subject is:{}".format(self._name,self._subject)) if __name__ == '__main__':t = Teacher("A","math")t.show()t.name = "B"t.subject = "English"t.show()

    注意

    這里@property必須在setter前面初始化,這個應該很容易理解,因為解釋器讀程序的時候是從上往下讀的。

    Special method

    要點

  • 之所有要實現special method,是為了讓自定義的class與python中的內置函數無縫銜接
  • python中有大量的內置函數,而這些函數中絕大部分是special method
  • python中的special method :https://rszalski.github.io/magicmethods/
  • 代碼

    class A:def __init__(self):passdef __str__(self):return "I am str"def __len__(self):return 15def __bool__(self):return Falseif __name__ == '__main__':a = A()print(a,len(a),a==True)

    轉載于:https://www.cnblogs.com/aoru45/p/9937751.html

    總結

    以上是生活随笔為你收集整理的[学习总结] python语言学习总结 (三)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。