python 學習筆記3
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