python lib\idlelib\idle.py
字符串和編碼
unicode(str,'gb2312')與str.decode('gb2312')是一樣的,都是將gb2312編碼的str轉為unicode編碼
使用str.class可以查看str的編碼形式
由于Python源代碼也是一個文本文件,所以驾茴,當你的源代碼中包含中文的時候,在保存源代碼時迷郑,就需要務必指定保存為UTF-8編碼潜必。當Python解釋器讀取源代碼時,為了讓它按UTF-8編碼讀取力麸,我們通常在文件開頭寫上這兩行:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
第一行注釋是為了告訴Linux/OS X系統(tǒng),這是一個Python可執(zhí)行程序育韩,Windows系統(tǒng)會忽略這個注釋克蚂;
第二行注釋是為了告訴Python解釋器,按照UTF-8編碼讀取源代碼筋讨,否則埃叭,你在源代碼中寫的中文輸出可能會有亂碼。
申明了UTF-8編碼并不意味著你的.py文件就是UTF-8編碼的悉罕,必須并且要確保文本編輯器正在使用UTF-8 without BOM編碼.
list tuple
List
Python內(nèi)置的一種數(shù)據(jù)類型是列表:list赤屋。list是一種有序的集合,可以隨時添加和刪除其中的元素壁袄。
[ ]
表示
如下
>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates
['Michael', 'Bob', 'Tracy']
>>> classmates.pop(1)
'Jack'
>>> classmates
['Michael', 'Bob', 'Tracy']
>>> classmates.pop(1)
'Jack'
>>> classmates
['Michael', 'Bob', 'Tracy']
>>> classmates[1] = 'Sarah'
>>> classmates
['Michael', 'Sarah', 'Tracy']
Tuple
另一種有序列表叫元組:tuple类早。tuple和list非常類似,但是tuple一旦初始化就不能修改
( )
條件判斷
if <條件判斷1>:
<執(zhí)行1>
elif <條件判斷2>:
<執(zhí)行2>
elif <條件判斷3>:
<執(zhí)行3>
else:
<執(zhí)行4>
循環(huán)
for x in ...循環(huán)就是把每個元素代入變量x嗜逻,然后執(zhí)行縮進塊的語句涩僻。
sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
sum = sum + x
print(sum)
range()可以生成一個整數(shù)序列,再通過list()函數(shù)可以轉換為list。比如range(5)生成的序列是從0開始小于5的整數(shù)
>>> list(range(5))
[0, 1, 2, 3, 4]
第二種循環(huán)是while循環(huán)
n = 1
while n <= 100:
if n > 10: # 當n = 11時栈顷,條件滿足令哟,執(zhí)行break語句
break # break語句會結束當前循環(huán)
print(n)
n = n + 1
print('END')
執(zhí)行上面的代碼可以看到,打印出1~10后妨蛹,緊接著打印END屏富,程序結束.
循環(huán)是讓計算機做重復任務的有效的方法。
break語句可以在循環(huán)過程中直接退出循環(huán)蛙卤,而continue語句可以提前結束本輪循環(huán)狠半,并直接開始下一輪循環(huán)噩死。這兩個語句通常都必須配合if語句使用。
要特別注意神年,不要濫用break和continue語句已维。break和continue會造成代碼執(zhí)行邏輯分叉過多,容易出錯已日。大多數(shù)循環(huán)并不需要用到break和continue語句垛耳,上面的兩個例子,都可以通過改寫循環(huán)條件或者修改循環(huán)邏輯飘千,去掉break和continue語句堂鲜。
有些時候,如果代碼寫得有問題护奈,會讓程序陷入“死循環(huán)”缔莲,也就是永遠循環(huán)下去。這時可以用Ctrl+C退出程序霉旗,或者強制結束Python進程痴奏。
dict & set
dict
{ }
表示
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95
>>> d.pop('Bob')
75
>>> d
{'Michael': 95, 'Tracy': 85}
和list比較,dict有以下幾個特點:
查找和插入的速度極快厌秒,不會隨著key的增加而變慢读拆;
需要占用大量的內(nèi)存,內(nèi)存浪費多鸵闪。
而list相反:
查找和插入的時間隨著元素的增加而增加建椰;
占用空間小,浪費內(nèi)存很少岛马。
所以,dict是用空間來換取時間的一種方法屠列。
dict可以用在需要高速查找的很多地方啦逆,在Python代碼中幾乎無處不在,正確使用dict非常重要笛洛,需要牢記的第一條就是dict的key必須是不可變對象夏志。
set
set和dict類似,也是一組key的集合苛让,但不存儲value沟蔑。由于key不能重復,所以狱杰,在set中瘦材,沒有重復的key。
要創(chuàng)建一個set仿畸,需要提供一個list作為輸入集合:
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}
注意食棕,傳入的參數(shù)[1, 2, 3]是一個list朗和,而顯示的{1, 2, 3}只是告訴你這個set內(nèi)部有1,2簿晓,3這3個元素眶拉,顯示的順序也不表示set是有序的。憔儿。
重復元素在set中自動被過濾:
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}
通過add(key)方法可以添加元素到set中忆植,可以重復添加,但不會有效果
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(4)
>>> s
{1, 2, 3, 4}
通過remove(key)方法可以刪除元素:
>>> s.remove(4)
>>> s
{1, 2, 3}
set和dict的唯一區(qū)別僅在于沒有存儲對應的value谒臼,但是朝刊,set的原理和dict一樣,所以屋休,同樣不可以放入可變對象坞古,因為無法判斷兩個可變對象是否相等,也就無法保證set內(nèi)部“不會有重復元素”劫樟。試試把list放入set痪枫,看看是否會報錯。
再議不可變對象
上面我們講了叠艳,str是不變對象奶陈,而list是可變對象。
函數(shù)
http://docs.python.org/3/library/functions.html#abs
高級特性
迭代器
Iterable 可迭代對象
可以直接作用于for循環(huán)的對象統(tǒng)稱為可迭代對象:Iterable附较。
包括:
- list, tuple,dict,set,str 等
- generator 生成器
用
from collections import Iterable
isinstance(xxxx, Iterable) #判斷
Iterator 迭代器
而生成器不但可以作用于for
循環(huán)吃粒,還可以被next()
函數(shù)不斷調用并返回下一個值,直到最后拋出StopIteration
錯誤表示無法繼續(xù)返回下一個值了拒课。
可以被next()
函數(shù)調用并不斷返回下一個值的對象稱為迭代器:Iterator
徐勃。
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
生成器都是Iterator對象,但list早像、dict僻肖、str雖然是Iterable,卻不是Iterator卢鹦。
把list臀脏、dict、str等Iterable變成Iterator可以使用iter()函數(shù):
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
小結
凡是可作用于for循環(huán)的對象都是Iterable類型冀自;
凡是可作用于next()函數(shù)的對象都是Iterator類型揉稚,它們表示一個惰性計算的序列;
集合數(shù)據(jù)類型如list熬粗、dict搀玖、str等是Iterable但不是Iterator,不過可以通過iter()函數(shù)獲得一個Iterator對象驻呐。
Python的for循環(huán)本質上就是通過不斷調用next()函數(shù)實現(xiàn)的巷怜,例如:
for x in [1, 2, 3, 4, 5]:
pass
實際上完全等價于:
# 首先獲得Iterator對象:
it = iter([1, 2, 3, 4, 5])
# 循環(huán):
while True:
try:
# 獲得下一個值:
x = next(it)
except StopIteration:
# 遇到StopIteration就退出循環(huán)
break
函數(shù)式編程
高階函數(shù) Higher-order function
map/reduce
我們先看map葛超。map()函數(shù)接收兩個參數(shù),一個是函數(shù)延塑,一個是Iterable绣张,map將傳入的函數(shù)依次作用到序列的每個元素,并把結果作為新的Iterator返回关带。
>>> def f(x):
... return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
map等價于如下
L = []
for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
L.append(f(n))
print(L)
再看reduce的用法侥涵。reduce把一個函數(shù)作用在一個序列[x1, x2, x3, ...]上,這個函數(shù)必須接收兩個參數(shù)宋雏,reduce把結果繼續(xù)和序列的下一個元素做累積計算芜飘,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
比方說對一個序列求和,就可以用reduce實現(xiàn):
>>> from functools import reduce
>>> def add(x, y):
... return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25
filter
sorted
>>> sorted([5, 2, 3, 1, 4])
[1, 2, 3, 4, 5]
返回函數(shù)
模塊
使用模塊
面向對象編程
類和實例
訪問限制
如果要讓內(nèi)部屬性不被外部訪問磨总,可以把屬性的名稱前加上兩個下劃線嗦明,在Python中,實例的變量名如果以開頭蚪燕,就變成了一個私有變量(private)
需要注意的是娶牌,在Python中,變量名類似xxx的馆纳,也就是以雙下劃線開頭诗良,并且以雙下劃線結尾的,是特殊變量鲁驶,特殊變量是可以直接訪問的鉴裹,不是private變量,所以钥弯,不能用name径荔、score這樣的變量名。
有些時候脆霎,你會看到以一個下劃線開頭的實例變量名总处,比如_name,這樣的實例變量外部是可以訪問的绪穆,但是,按照約定俗成的規(guī)定虱岂,當你看到這樣的變量時玖院,意思就是,“雖然我可以被訪問第岖,但是难菌,請把我視為私有變量,不要隨意訪問”蔑滓。
雙下劃線開頭的實例變量是不是一定不能從外部訪問呢郊酒?其實也不是遇绞。不能直接訪問__name是因為Python解釋器對外把__name變量改成了_Student__name,所以燎窘,仍然可以通過_Student__name來訪問__name變量:
繼承和多態(tài)
獲取對象信息
使用type()
使用isinstance()
總是優(yōu)先使用isinstance()判斷類型摹闽,可以將指定類型及其子類“一網(wǎng)打盡”。
使用dir()
>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
僅僅把屬性和方法列出來是不夠的褐健,配合getattr()
付鹿、setattr()
以及hasattr()
,我們可以直接操作一個對象的狀態(tài):
實例屬性和類屬性
面向對象高級編程
使用_slots_
正常情況下蚜迅,當我們定義了一個class舵匾,創(chuàng)建了一個class的實例后,我們可以給該實例綁定任何屬性和方法谁不,這就是動態(tài)語言的靈活性坐梯。先定義class:
class Student(object):
pass
然后,嘗試給實例綁定一個屬性:
>>> s = Student()
>>> s.name = 'Michael' # 動態(tài)給實例綁定一個屬性
>>> print(s.name)
Michael
還可以嘗試給實例綁定一個方法:
>>> def set_age(self, age): # 定義一個函數(shù)作為實例方法
... self.age = age
...
>>> from types import MethodType
>>> s.set_age = MethodType(set_age, s) # 給實例綁定一個方法
>>> s.set_age(25) # 調用實例方法
>>> s.age # 測試結果
25
但是刹帕,給一個實例綁定的方法吵血,對另一個實例是不起作用的:
>>> s2 = Student() # 創(chuàng)建新的實例
>>> s2.set_age(25) # 嘗試調用方法
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'set_age'
為了給所有實例都綁定方法,可以給class綁定方法:
>>> def set_score(self, score):
... self.score = score
...
>>> Student.set_score = set_score
給class綁定方法后轩拨,所有實例均可調用:
>>> s.set_score(100)
>>> s.score
100
>>> s2.set_score(99)
>>> s2.score
99
通常情況下践瓷,上面的set_score方法可以直接定義在class中,但動態(tài)綁定允許我們在程序運行的過程中動態(tài)給class加上功能亡蓉,這在靜態(tài)語言中很難實現(xiàn)晕翠。
使用slots
但是,如果我們想要限制實例的屬性怎么辦砍濒?比如淋肾,只允許對Student實例添加name和age屬性。
為了達到限制的目的爸邢,Python允許在定義class的時候樊卓,定義一個特殊的slots變量,來限制該class實例能添加的屬性:
class Student(object):
__slots__ = ('name', 'age') # 用tuple定義允許綁定的屬性名稱
然后杠河,我們試試:
>>> s = Student() # 創(chuàng)建新的實例
>>> s.name = 'Michael' # 綁定屬性'name'
>>> s.age = 25 # 綁定屬性'age'
>>> s.score = 99 # 綁定屬性'score'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'
由于'score'沒有被放到slots中碌尔,所以不能綁定score屬性,試圖綁定score將得到AttributeError的錯誤券敌。
使用slots要注意唾戚,slots定義的屬性僅對當前類實例起作用,對繼承的子類是不起作用的:
>>> class GraduateStudent(Student):
... pass
...
>>> g = GraduateStudent()
>>> g.score = 9999
除非在子類中也定義slots待诅,這樣叹坦,子類實例允許定義的屬性就是自身的slots加上父類的slots。
使用@property
class Screen(object):
@property
def width(self):
return self._width
@width.setter
def width(self, width):
self._width = width
@property
def height(self):
return self._height
@height.setter
def height(self, height):
self._height = height
@property
def resolution(self):
return self._width*self._height