1. 程式人生 > >python 學習筆記3

python 學習筆記3

不存在 而且 以及 lte int code 裝飾器 per err

9 高階函數

(1) map()函數接收兩個參數,一個是函數,一個是Iterable,map將傳入的函數依次作用到序列的每個元素,並把結果作為新的Iterator返回。list(map(str, [1, 2, 3]))

(2) reduce把一個函數作用在一個序列[x1, x2, x3, …]上,這個函數必須接收兩個參數,reduce把結果繼續和序列的下一個元素做累積計算。from functools import reduce

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

(3) filter()也接收一個函數和一個序列。filter()把傳入的函數依次作用於每個元素,然後根據返回值是True還是False決定保留還是丟棄該元素。filter()

函數返回的是一個Iterator.

(4) sorted()排序sorted([‘bob‘, ‘about‘, ‘Zoo‘, ‘Credit‘], key=str.lower, reverse=True)

10 函數式編程

(1) 高階函數除了可以接受函數作為參數外,還可以把函數作為結果值返回。

調用lazy_sum()返回函數,內部函數sum可以引用外部函數lazy_sum的參數和局部變量,當lazy_sum返回函數sum時,相關參數和變量都保存在返回的函數中,稱為閉包。

返回的函數並沒有立刻執行,f=lazy_sum(1,2,3) 調用了 f()函數才執行。

返回函數不要引用任何循環變量,或者後續會發生變化的變量。

如果一定要引用循環變量,方法是再創建一個函數,用該函數的參數綁定循環變量當前的值,無論該循環變量後續如何更改,已綁定到函數參數的值不變。

def lazy_sum(*args):
    def sum():
        ax=0
        for n in args:
            ax=ax+n
        return ax
    return sum

(2) 匿名函數, 關鍵字lambda表示匿名函數,冒號前面的x表示函數參數, 冒號後面是表達式。lambda x: x * x

(3) 裝飾器

(4) 偏函數,當函數的參數個數太多,需要簡化時,使用functools.partial

可以創建一個新的函數,這個新函數可以固定住原函數的部分參數,從而在調用時更簡單。

11 模塊

每一個包目錄下面都會有一個__init__.py的文件,這個文件是必須存在的,否則,Python就把這個目錄當成普通目錄,而不是一個包。

__init__.py可以是空文件,也可以有Python代碼,因為__init__.py本身就是一個模塊。

類似__xxx__這樣的變量是特殊變量,可以被直接引用,但是有特殊用途,比如上面的__author__,__name__就是特殊變量。

類似_xxx__xxx這樣的函數或變量就是非公開的(private),不應該被直接引用,比如_abc,__abc等;

12 類

(1)由於類可以起到模板的作用,因此,可以在創建實例的時候,把一些我們認為必須綁定的屬性強制填寫進去。

通過定義一個特殊的__init__方法。__init__方法的第一個參數永遠是self,表示創建的實例本身

因此,在__init__方法內部,就可以把各種屬性綁定到self,因為self就指向創建的實例本身。

方法就是與實例綁定的函數,和普通函數不同,方法可以直接訪問實例的數據;

和靜態語言不同,Python允許對實例變量綁定任何屬性如bart.age

class Student(object):

    def __init__(self, name, score):
        self.name = name
        self.score = score

    def print_score(self):
        print(‘%s: %s‘ % (self.name, self.score))
bart = Student(‘Bart Simpson‘, 59)
bart.age=12

(2)如果要讓內部屬性不被外部訪問,可以把屬性的名稱前加上兩個下劃線__

在Python中,實例的變量名如果以__開頭,就變成了一個私有變量(private)self.__name=name,外部代碼要獲取name, 可以給Student類增加方法.

(3)繼承可以把父類的所有功能都直接拿過來,子類只需要新增自己特有的方法,也可以把父類不適合的方法覆蓋重寫。

(4)isinstance()判斷的是一個對象是否是該類型本身,或者位於該類型的父繼承鏈上。isinstance([1, 2, 3], (list, tuple) ;

dir()函數獲得一個對象的所有屬性方法;

getattr()、setattr()以及hasattr(),可以直接操作一個對象的屬性或方法;getattr(obj, ‘z‘, 404) # 獲取屬性‘z‘,如果不存在,返回默認值404

(5)類屬性,直接在class中定義屬性。相同名稱的實例屬性將屏蔽掉類屬性。

(6)給實例綁定一個方法,

s = Student()
def qage(self,age):
    self.age=age
from types import MethodType
s.age=MethodType(qage,s)
s.age(9)

給類綁定方法,給class綁定方法後,所有實例均可調用 Student.qage=qage

想要限制實例的屬性, 在定義class的時候,定義一個特殊的__slots__變量,來限制該class實例能添加的屬性. class Student(object):

__slots__ = (‘name‘, ‘age‘) # 用tuple定義允許綁定的屬性名稱

_slots__定義的屬性僅對當前類實例起作用,對繼承的子類是不起作用的, 除非在子類中也定義_slots__這樣,子類實例允許定義的屬性就是自身的_slots__加上父類的`slots_

(7)Python內置的@property裝飾器就是負責把一個方法變成屬性調用的。

class Student(object):
    @property
    def age(self):
        return self.__age
    @age.setter
    def age(self,value):
        if not isinstance(value,int):
            raise ValueError(‘wrong‘)
        self.__age=value    

(8)__str__:print出實例,不但好看,而且容易看出實例內部重要的數據。 直接顯示變量調用的不是__str__()而是__repr__()

兩者的區別是__str__()返回用戶看到的字符串,而__repr__()返回程序開發者看到的字符串,也就是說__repr__()是為調試服務的。__repr__()定義後可直接顯示。

class a(object):
    def __init__(self,name):
        self.__name=name
    def __str__(self):
        return ‘hello %s‘%self.__name
    __repr__=__str__

python 學習筆記3