變量
轉義:加很多\,為了簡化,Python還允許用r''表示''內部的字符串默認不轉義
換行:允許用'''...'''的格式表示多行內容
空值:用None表示
字符串和編碼:
Unicode把所有語言都統一到一套編碼里,本著節約的精神,又出現了把Unicode編碼轉化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字符根據不同的數字大小編碼成1-6個字節,常用的英文字母被編碼成1個字節,漢字通常是3個字節,只有很生僻的字符才會被編碼成4-6個字節。如果你要傳輸的文本包含大量英文字符,用UTF-8編碼就能節省空間:
len()函數:
要計算str包含多少個字符,可以用len()函數:
如果換成bytes,len()函數就計算字節數
當Python解釋器讀取源代碼時,為了讓它按UTF-8編碼讀取,我們通常在文件開頭寫上這兩行:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
常見的占位符有:
%d
整數
%f
浮點數
%s
字符串
%x
十六進制整數
list和tuple:
l列表:list。list是一種有序的集合,可以隨時添加和刪除其中的元素。list里面的元素的數據類型也可以不同
得索引是從0開始的.如果要取最后一個元素,除了計算索引位置外,還可以用-1做索引;
插入:可以往list中追加元素到末尾也可以把元素插入到指定的位置,比如索引號為1的位置:
>>>classmates.insert(1,'Jack')
刪除:list末尾的元素,用pop()方法,刪除指定位置的元素,用pop(i)方法,其中i是索引位置;
替換:直接賦值給對應的索引位
ltuple和list非常類似,但是tuple一旦初始化就不能修改。只有1個元素的tuple定義時必須加一個逗號,,來消除歧義
if的完整語句:
if<條件判斷1>:
<執行1>
elif<條件判斷2>:
<執行2>
elif<條件判斷3>:
<執行3>
else:
<執行4>
dict:dict全稱dictionary,在其他語言中也稱為map,使用鍵-值(key-value)存儲
set:也是一組key的集合,但不存儲value。由于key不能重復,所以,在set中,沒有重復的key。
切片:L[0:3]表示,從索引0開始取,直到索引3為止,但不包括索引3。即索引0,1,2,正好是3個元素。如果第一個索引是0,還可以省略,也支持倒數切片L[-2:]
生成器:一邊循環一邊計算的機制
第一種方法很簡單,只要把一個列表生成式的[]改成(),就創建了一個generator
generator保存的是算法,每次調用next(g),就計算出g的下一個元素的值,直到計算到最后一個元素,沒有更多的元素時,拋出StopIteration的錯誤
repe::器:可以直接作用于for循環的對象統稱為可迭代對象:Iterable
可以使用isinstance()判斷一個對象是否是Iterable對象
map/reduce:map()函數接收兩個參數,一個是函數,一個是Iterable,map將傳入的函數依次作用到序列的每個元素,并把結果作為新的Iterator返回。
reduce把一個函數作用在一個序列[x1, x2, x3, ...]上,這個函數必須接收兩個參數,reduce把結果繼續和序列的下一個元素做累積計算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
filter:filter()把傳入的函數依次作用于每個元素,然后根據返回值是True還是False決定保留還是丟棄該元素filter()把傳入的函數依次作用于每個元素,然后根據返回值是True還是False決定保留還是丟棄該元素
s.strip(rm)刪除s字符串中開頭、結尾處,位于rm刪除序列的字符,當rm為空時,默認刪除空白符(包括'\n', '\r',? '\t',? ' ')
sorted:排序算法
可以接收一個key函數來實現自定義的排序
返回函數:我們在函數lazy_sum中又定義了函數sum,并且,內部函數sum可以引用外部函數lazy_sum的參數和局部變量,當lazy_sum返回函數sum時,相關參數和變量都保存在返回的函數中,這種稱為“閉包(Closure)”的程序結構擁有極大的威力。
返回閉包時牢記的一點就是:返回函數不要引用任何循環變量,或者后續會發生變化的變量。
匿名函數:lambda
只能有一個表達式,不用寫return,返回值就是該表達式的結果
裝飾器:
假設我們要增強now()函數的功能,比如,在函數調用前后自動打印日志,但又不希望修改now()函數的定義,這種在代碼運行期間動態增加功能的方式,稱之為“裝飾器”(Decorator)。
decorator就是一個:使用函數作參數并且返回函數的函數
因為返回的那個wrapper()函數名字就是'wrapper',所以,需要把原始函數的__name__等屬性復制到wrapper()函數中,否則,有些依賴函數簽名的代碼執行就會出錯。
不需要編寫wrapper.__name__
= func.__name__這樣的代碼,Python內置的functools.wraps就是干這個事的,所以,一個完整的decorator的寫法如下:
importfunctools
deflog(func):
@functools.wraps(func)
defwrapper(*args, **kw):
print('call %s():'% func.__name__)
returnfunc(*args, **kw)
returnwrapper
只需記住在定義wrapper()的前面加上@functools.wraps(func)即可。并且記得import functools
偏函數:
import functools
簡單總結functools.partial的作用就是,把一個函數的某些參數給固定住(也就是設置默認值),返回一個新的函數,調用這個新函數會更簡單。
當函數的參數個數太多,需要簡化時,使用functools.partial可以創建一個新的函數,這個新函數可以固定住原函數的部分參數,從而在調用時更簡單。
模塊:使用模塊還可以避免函數名和變量名沖突。相同名字的函數和變量完全可以分別存在不同的模塊中。
不要與內置函數名字沖突
Built-in Functions
abs()dict()help()min()setattr()all()dir()hex()next()slice()any()divmod()id()object()sorted()ascii()enumerate()input()oct()staticmethod()bin()eval()int()open()str()bool()exec()isinstance()ord()sum()bytearray()filter()issubclass()pow()super()bytes()float()iter()print()tuple()callable()format()len()property()type()chr()frozenset()list()range()vars()classmethod()getattr()locals()repr()zip()compile()globals()map()reversed()__import__()complex()hasattr()max()round()delattr()hash()memoryview()set()
為了避免模塊名沖突,Python又引入了按目錄來組織模塊的方法,稱為包(Package)。
引入了包以后,只要頂層的包名不與別人沖突,那所有模塊都不會與別人沖突。
每一個包目錄下面都會有一個__init__.py的文件,這個文件是必須存在的。
模塊的使用:(一下是標準文件模板)#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a test module '#模塊的文檔注釋
__author__ ='Michael Liao'
作用域(函數和變量名):為了封裝和抽象
lPublic:可以被直接引用
__xxx__特殊變量,可被直接引用,也有特殊用途。自己的變量一般不用這種變量名。
lPrivate:不應被直接引用
_xxx和__xxx
外部不需要引用的函數全部定義成private,只有外部需要引用的才定義為public。
安裝第三方模塊:
在Python中,安裝第三方模塊,是通過包管理工具pip完成的。
打開cmd,輸入:pip install xxx
加載模塊:import xxx(!!!)
如果提示:name”xxx” not defined或者not found很有可能是沒有import
默認情況下,Python解釋器會搜索當前目錄、所有已安裝的內置模塊和第三方模塊,搜索路徑存放在sys模塊的path變量中:
面向對象編程:
面向對象編程——Object
Oriented Programming,簡稱OOP,是一種程序設計思想。OOP把對象作為程序的基本單元,一個對象包含了數據和操作數據的函數。
init稱為構造函數或者初始程序,初始化類或對象的實例,在這個_init_下,新創立的對象就是self.
class Dog: definit(self, legs,colour): self.legs = legs self.colour = colour
fido = Dog(4, "brown") spot =Dog(3, "mostly yellow"
對一只狗來說:_init_就是第一次寫了一些信息的出生證明,幾斤重,在哪里出生等等
變量self就是它以后會成為的那條狗。而self.color或者self.legs或self.xx就是它今后的改變會成為怎么樣一只狗,黃色3條腿或其他
然后有個例子關于Class中的變量和_init_函數中的變量的差別class MyClass(object): i = 123 def _init_(self): self.i =
345 print(MyClass().i)345 print(MyClass.i)123
類和實例:
classStudent(object):
pass
class后面緊接著是類名,即Student,類名通常是大寫開頭的單詞,緊接著是(object),表示該類是從哪個類繼承下來的,繼承的概念我們后面再講,通常,如果沒有合適的繼承類,就使用object類,這是所有類最終都會繼承的類。
由于類可以起到模板的作用,因此,可以在創建實例的時候,把一些我們認為必須綁定的屬性強制填寫進去。通過定義一個特殊的__init__方法,在創建實例的時候,就把name,score等屬性綁上去:
注意:特殊方法“init”前后有兩個下劃線!!!
classStudent(object):
def__init__(self, name, score):
self.name = name
self.score = score
數據封裝:
直接在Student類的內部定義訪問數據的函數,這樣,就把“數據”給封裝起來了。這些封裝數據的函數是和Student類本身是關聯起來的,我們稱之為類的方法:
方法就是與實例綁定的函數,和普通函數不同,方法可以直接訪問實例的數據;
和靜態語言不同,Python允許對實例變量綁定任何數據,也就是說,對于兩個實例變量,雖然它們都是同一個類的不同實例,但擁有的變量名稱都可能不同:
也就是說,對A在類外定義了新的age屬性,但B是沒有這個屬性的!
訪問限制:
如果要讓內部屬性不被外部訪問,可以把屬性的名稱前加上兩個下劃線__,在Python中,實例的變量名如果以__開頭,就變成了一個私有變量(private),
l只有內部可以訪問,外部不能訪問:直接用bart.__name就無法得到結果
l這樣就確保了外部代碼不能隨意修改對象內部的狀態
l外部代碼要獲取變量:在類中定義:get_name函數
l又要允許外部代碼修改score,給Student類增加set_score方法:
在方法中,可以對參數做檢查,避免傳入無效的參數
l需要注意的是,在Python中,變量名類似__xxx__的,也就是以雙下劃線開頭,并且以雙下劃線結尾的,是特殊變量,特殊變量是可以直接訪問的,不是private變量,所以,不能用__name__、__score__這樣的變量名。
l看到以一個下劃線開頭的實例變量名,比如_name,這樣的實例變量外部是可以訪問的,但是,按照約定俗成的規定,當你看到這樣的變量時,意思就是,“雖然我可以被訪問,但是,請把我視為私有變量,不要隨意訪問”。
l不能直接訪問__name是因為Python解釋器對外把__name變量改成了_Student__name
l雖然可以通過_Student__name來訪問__name變量,但不同版本的Python解釋器可能會把__name改成不同的變量名
l注意下面的這種錯誤寫法:
l>>>bart = Student('Bart Simpson',98)
l>>>bart.get_name()
l'Bart Simpson'
l>>>bart.__name ='New Name'#設置__name變量!
l>>>bart.__name
l'New Name'
繼承和多態:
在繼承關系中,如果一個實例的數據類型是某個子類,那它的數據類型也可以被看做是父類。但是,反過來就不行。
定義父類:classAnimal(object):
Pass
定義子類:class Dog(Animal):
Pass
獲取對象信息:
1.先判斷對象類型--type()
type(對象)函數返回的是什么類型呢?它返回對應的Class類型
2.判斷class的類型—isinstance()
Isinstance(對象,類名)。可反映class的繼承關系
3.能用type()判斷的基本類型也可以用isinstance()判斷
4.還可以判斷一個變量是否是某些類型中的一種
isinstance([1,2,3], (list, tuple))
就是判斷是不是屬于list或者tuple中的一種
5.要獲得一個對象的所有屬性和方法—dir()
返回的是一個包含字符串的list
6.僅把屬性和方法列出來是不夠的,配合getattr()、setattr()以及hasattr(),我們可以直接操作一個對象的狀態
hasattr(obj,'x')#有屬性'x'嗎?
setattr(obj,'y',19)#設置一個屬性'y'
getattr(obj,'y')#獲取屬性'y'
getattr(obj,'z',404)#獲取屬性'z',如果不存在,返回默認值404
實例屬性和類屬性:
lStudent類本身需要綁定一個屬性呢?可以直接在class中定義屬性,這種屬性是類屬性,歸Student類所有
l實例綁定屬性的方法是通過實例變量,或者通過self變量