學習一門新的語言,應當抓住語言的共有特性,這樣容易觸類旁通,學習起來也十分的快捷愉悅 而語言的特性大約有以下元素 變數定義與類型 算術符號與邏輯符號 for 迴圈與 while 迴圈 數組,線性表等一些常用的數據結構 函數的定義與調用 遞歸 靜態類型系統 類型的推導 lambda 函數 面向對象 垃 ...
學習一門新的語言,應當抓住語言的共有特性,這樣容易觸類旁通,學習起來也十分的快捷愉悅
而語言的特性大約有以下元素
- 變數定義與類型
- 算術符號與邏輯符號
- for 迴圈與 while 迴圈
- 數組,線性表等一些常用的數據結構
- 函數的定義與調用
- 遞歸
- 靜態類型系統
- 類型的推導
- lambda 函數
- 面向對象
- 垃圾回收
- 異常檢測
如果你對一個語言以上的元素都有了大致瞭解(事實上其實並不需要花太多時間),那麼你就可以愉快的開始使用啦~
1.變數的定義與類型
變數的定義
python里變數的定義十分簡單 不需要像java里需要進行聲明
例如i = 0
變數的類型
Pyhton里的變數類型分為整數型(int)
浮點型(float)
字元型(str)
布爾值類型(bool)
其中bool類型的對錯是首字母大寫的True
與False
,非0的字元(包括int,float,str)如果轉義會被轉成True
而0則是False
這點有點類似於Javascript
字元串的格式化
- python中的字元串支持參數的方式 如
"{a} love {b}".format(a="i", b="u")
結果為i love u
可以看作是使用了變數進行了代替 - 同樣可以使用數字位置的參數進行替換如
'{0} love {1}.format('i', 'u')'
結果為i love u
- 如果限制格式那麼使用 : 例如
'{0:.2f}'.format(45.5688)
結果為45.57
- 要進行格式化操作的話 這樣使用
'%c' % 97
結果為a
,因為%c 是進行ASCII碼的轉化 ,多個參數使用元組或者字典'%d + %d = %d' % (4,5,9.1)
結果為4 + 5 = 9
, 這裡用一個列表介紹各種格式符號的意思
符號 | 含義 |
---|---|
%c | 格式化ASCII碼 |
%d | 格式化整數 |
- 當然還有一些是用來輔助操作的
符號 | 說明 |
---|---|
m.n | m是顯式的最小總寬度,n是小數點後的位數 |
- | 用於左對齊 |
+ | 在正數前面顯式加號 |
# | 在8進位前面顯示0,在16進位數前面顯式0x或者0X |
0 | 顯式的數字前面填充0取代空格 |
2.邏輯符號與運算符符號
邏輯符號
- and or not 對應java的 && || !
運算符
- 基本運算符包括
+ - * / ** //
- ** 的意思是階乘 例如 3 ** 2 = \(3^2\) = 9
- python里/ 除號預設是float,若要變成類似java的兩個取整的,就使用//符號 例如
3/2=1.5
,3//2=1
3.For迴圈與While迴圈
for迴圈
for i in range(0,10):
print (i, end='')
輸出結果0 1 2 3 4 5 6 7 8 9
pyhton里的for迴圈類似於java5中的foreach迴圈,對迴圈體里的每個對象進行操作
while迴圈
i = 0
while i < 10:
print(i, end=' ')
i += 1
輸出結果0 1 2 3 4 5 6 7 8 9
需要註意的是python里的迴圈體語法後面要加上一個冒號哦 :)
4.數組,元組與線性表
數組中常用的api
可以通過dir(list)
來查看相關api
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
- 構建一個數組
array = [1,2,3,'hello']
- 要添加元素使用append,
array.append(x)
- extend類似於java里的addAll
array.extend(list2())
- remove
array.remove('hello')
- 按照下標刪除數組裡的東西
del array[1]
,如果是del array
,那會直接把這個那個數組刪除掉 - 也可以使用pop()函數
array.pop()
,不寫參數時是預設刪除最後一個元素,可以通過填寫下標來刪除指定的元素 數組的分片
array[a:b]
,a代表可以的索引值,b代表結束的索引值(但是不包括這個元素),例如array[0:2]
就等於
[1,2]
,也可以不指定a或者b,這樣是預設從頭開始,一直到結尾,例如array[:]
獲得了原數組的拷貝[1,2,3,'hello']
- reverse,
array.reverse()
數組列表反轉 - count,
array.count(1)
,統計數組裡1出現的次數 - index,
array.index(1)
返回指定元素的下標 其他方法自己看api啦
數組中的操作符
- 使用操作符 + 對數組進行拼接,例如
list1 = [1, 2] list2 = [3, 4] list3 = list1 + list2
,那麼list3裡面內容就是[1,2,3,4]
但是需要註意的是 + 操作符兩邊的對象類型要保持一致list3 = list1 + 3
顯然就是錯誤的 - 使用操作符 * 可以達到數組的拷貝與拼接例如進行
array *= 2
的操作過後array =[1,2,3,'hello',1,2,3,'hello']
- 使用操作符 = 可以達到數組地址的引用
in
與not in
返回一個bool類型的結果,例如'hello' in array
返回True'hello' not in array
返回False
元組(tuple)
- 元組的操作和數組十分類似,不同的是元組是不可變的,可以理解為java里的final類型的數組
- 元組的構建的核心是 , 逗號
tuple01 = (1)
,這樣的構建方式type(tuple01)的結果就是int, 正確的構建方式是類似於這種tuple01 = (1,)
tuple01 = (1, 2, )
,如果要構建一個空的元祖使用tuple01 = ()
如果要對元組進行更新,刪除,添加等改變狀態的操作,一般是使用: 重新構建出一個新的元組,例子如下
tuple01 = (1, 2, 3) #下麵我想要在該元組後面加入一個新的元素 tuple02 = tuple01[:] + (4,) print (tuple02) #那麼tuple02 = [1,2,3,4] , 那麼更新與刪除的操作與上面就同樣類似了
線性表
集合的本質是由數組構成的有序線性表,因此大部分語法與數組相同
集合的構建
list()
空列表list(iterable)
參數為可迭代的對象>>> b= 'I LOVE YOU' >>> b = list(b) >>> b ['I', ' ', 'L', 'O', 'V', 'E', ' ', 'Y', 'O', 'U']
- 集合的正常操作api與數組和元組十分類似,可以使用help(list)進行查看
- 一些集合中常用的輔助函數 假設有這麼一個集合
list1 = list([1,2])
sum()
求和sum(list)
結果為3
max(),min()
最大值與最小值enumerate()
將索引與值拼接成一個元組返回list(enumerate(list1))
結果為[(0, 1), (1, 2)]
zip
打包list2 = list([3,4,5])
根據索引值將2個集合的數據拼成一個元組返回 例list(zip(list1,list2))
結果為[(1, 3), (2, 4)]
,對應不上的就捨去了,所以5沒有在結果中
5.函數的定義與調用
函數的定義
def helloWorld():
print ('i love programe!')
python中的函數參數形式
指定參數傳遞
輸出結果為def say(name, word): print (name, 'say', word) say(word = 'hello!', name = 'I')
I say hello!
預設參數
def say(name = 'i' , word = 'helloWorld!'): print(name + '\r say \r ' + word say() say('you','good')
輸出結果為
>>> say() i say helloWorld! >>> say('you', 'good') you say good
參數列表
def say(*name): for x in name print (x) say(1,2,3)
輸出結果為
1,2,3
一般使用參數列表建議後面的參數使用預設參數例如def say(*name, word='say hello!'): for x in name: print (x, word)
函數(function )與過程(produce )
在python里沒有過程,只有函數,即使是沒有return的函數依舊有一個返回值,這點與java
不同
測試
def voidType():
print ("Hello World!")
#列印出該函數的返回值
print (voidType())
#使用type函數來獲得該函數的返回值
type(voidType())
結果如下
>>> print (voidType())
HelloWorld!
None
>>> type(voidType())
HelloWorld!
<class 'NoneType'>
可以看到列印的是None
,而使用type函數得到的結果是NoneType
,說明瞭在python中沒有produce只有function
函數關鍵字global
在python中的函數不能對外部變數進行修改,可以訪問,這點與java8的函數類似,也保持了函數無狀態的性質。
關鍵字global的使用,看下麵這個例子
count = 5; def myFun(): count = 10 print(count) myFun() print(count)
運行結果是
10 5
在python里如果在函數里定義了局部變數,變數名與全局變數相同(在上面的例子是count變數分別在外部和函數里被定義了一次),那麼函數體內使用的就是局部變數(採取了就近原則)
如果要定義全局變數,使用global關鍵字count = 5; def myFun(): global count #這裡的定義是不能直接賦值的,比如global count = 10 這種寫法 count = 10 print(count) myFun() print(count)
運行結果是
10 10
註意,這裡看起來是對全局變數進行了修改,但我的理解是這裡並不是進行修改,是內部重新定義了一個全局變數count,然後進行了賦值,自然就覆蓋掉了全局的變數,依舊沒有打破無狀態的原則。
與其他語言的對比
與java的對比
- 訪問與修改
在java中,在方法中可以訪問和修改全局變數 - 局部變數的定義
局部變數不能和全局變數同名,否則編譯不通過
與javaScriptd對比
1.訪問與修改
在javaScript中,與python一樣,函數中可以對全局變數進行訪問,但是不能修改
2.局部變數的定義
與pyhton相反,如果不加上關鍵字var
,則預設是全局變數,如果同名就直接頂替,必須加上關鍵字var
才聲明為局部變數
(在pyhton中是,不加關鍵字預設為局部變數,只有加上關鍵字global
才是全局變數)
內嵌函數
python中支持在函數體內定義函數,作用範圍限於函數體內
def fun1():
print ('fun1() is running!')
def fun2():
print('fun2() is running!')
fun1()
運行結果為
fun1() is running!
fun2() is running!
閉包
在上面已經提到,函數體內部可以訪問全局變數,但是在外部卻無法訪問局部變數,而閉包
就是提供了外部能夠訪問內部函數的變數和函數的一個入口,這點與javaScript
中的閉包概念一樣,有點類似於java類中提供的getset方法,而提供這個這麼一個訪問入口的函數,就稱之為閉包
簡單的說,閉包可以理解為"定義在一個函數內部的函數,提供了外部訪問的入口"
或者是"一個能夠讀取函數內局部變數的函數"
閉包的用途
1.上面提到的可以使得外部可以進行訪問
2.既然可以供外部訪問或是引用,那麼這些局部變數就可以被保存到記憶體中,並且這些局部變數所依賴的函數,也同樣的被保存了,不會被gc給回收掉。
下麵是一個閉包的例子
def fun1(x):
def fun2(y)
return x * y
return fun2
fun3 = fun1(2) # 這裡fun3獲得了fun2的引用,成功的訪問到了局部函數,所以fun2函數就是一個閉包
fun3(3) # 這裡結果是 2 * 3 = 6
再一個例子
def fun1():
x = 5
def fun2():
nonlocal x # 在python2.x中,無法對外部變數進行修改,但在3.x中,引入nonlocal關鍵字,則可以進行修改,debug查看之後發現,外部變數確確實實的被改變了,不過我覺得這打破了函數體內不能擁有狀態的這條性質....
x *= 5
return fun2()
fun2()# 運行結果為25
當然了這裡的fun2()同樣是一個閉包