學Python最簡單的方法是什麼?推薦閱讀:Python開發工程師成長魔法
本文由rever4433, Tocy, Tony, 南宮冰鬱, 透過樹葉的光等協作翻譯,發表於開源中國。
什麼是 Python ? Python 之父 Guido van Rossum 說:
Python是一種高階程式語言,其核心設計哲學是程式碼可讀性和語法,能夠讓程式員用很少的程式碼來表達自己的想法。
對於我來說,學習 Python 的首要原因是,Python 是一種可以優雅程式設計的語言。它能夠簡單自然地寫出程式碼和實現我的想法。
另一個原因是我們可以將 Python 用在很多地方:人工智慧、資料科學、Web 開發和機器學習等都可以使用 Python 來開發。Quora、Pinterest 和 Spotify 都使用 Python 來進行他們的後端 Web 開發。那麼讓我們來學習一下 Python 吧。
Python 基礎
1.變數
你可以把變數想象成一個用來儲存值的單詞。我們看個例子。
Python 中定義一個變數併為它賦值是很容易的。假如你想儲存數字 1 到變數 “one” ,讓我們試試看:
one = 1
超級簡單吧?你只需要把值 1 分配給變數 “one” 。
two = 2
some_number = 10000
只要你想,你可以把任意的 值 賦給任何其他的 變數 。正如你從上面看到的那樣,變數 “ two ” 儲存整型變數 2 , 變數 “ some_number ” 儲存 10000 。
除了整型,我們還可以使用布林值(True/Flase)、字串、浮點型和其他資料型別。
# booleans
true_boolean = True
false_boolean = False
# string
my_name = "Leandro Tk"
# float
book_price = 15.80
2.控制流程:條件陳述句
“ If ” 使用一個運算式來判斷一個陳述句是 True 還是 False ,如果是 True ,那麼執行 if 內的程式碼,例子如下:
if True:
print("Hello Python If")
if 2 > 1:
print("2 is greater than 1")
2 比 1 大,所以 print 程式碼被執行。
當“ if ”裡面的運算式是 false 時,“ else ” 陳述句將會執行。
if 1 > 2:
print("1 is greater than 2")
else:
print("1 is not greater than 2")
1 比 2 小,所以 “ else ” 裡面的程式碼會執行。
你也可以使用 “ elif ” 陳述句:
if 1 > 2:
print("1 is greater than 2")
elif 2 > 1:
print("1 is not greater than 2")
else:
print("1 is equal to 2")
3. 迴圈和迭代
在 Python 中,我們可以用不同的形式進行迭代。我會說下 while 和 for。
While 迴圈:當陳述句是 True 時,while 內部的程式碼塊會執行。所以下麵這段程式碼會打印出 1 到 10 。
num = 1
while num <= 10:
print(num)
num += 1
while 迴圈需要 迴圈條件 ,如果條件一直是 True ,它將會一直迭代,當 num 的值為 11 時,迴圈條件為 false 。
另一段程式碼可以幫你更好的理解 while 陳述句的用法:
loop_condition = True
while loop_condition:
print("Loop Condition keeps: %s" %(loop_condition))
loop_condition = False
迴圈條件是 True 所以會一直迭代,直到為 False 。
For 迴圈:你可以在程式碼塊上應用變數 “ num ” ,而 “for” 陳述句將為你迭代它。此程式碼將列印與 while 中相同的程式碼:從 1 到 10 。
for i in range(1, 11):
print(i)
瞧見沒?這太簡單了。i 的範圍從 1 開始一直到第 11 個元素(10是第十個元素)
List:集合 | 陣列 | 資料結構
假如你想要在一個變數裡儲存整數 1 ,但是你也要儲存 2 和 3 , 4 , 5 ……
不是用成百上千個變數,我有別的方法儲存這些我想要儲存的整數嗎?你已經猜到了,確實有別的儲存它們的方法。
串列是一個集合,它能夠儲存一列值(就像你想要儲存的這些),那麼讓我們來用一下它:
my_integers = [1, 2, 3, 4, 5]
這真的很簡單。我們建立了一個叫做 my_integer 的陣列並且把資料存到了裡面。
也許你會問:“我要怎樣獲取陣列裡的值?”
問的好。串列有一個叫做索引的概念。第一個元素的下表是索引0(0)。第二個的索引是1,以此類推,你應該明白的。
為了使它更加簡潔,我們可以用它的索引代表陣列元素。我畫了出來:
用 Python 的語法,也很好去理解:
my_integers = [5, 7, 1, 3, 4]
print(my_integers[0]) # 5
print(my_integers[1]) # 7
print(my_integers[4]) # 4
假如你不想存整數。你只想去存一些字串,像你親戚名字的串列。我的看起來是類似這樣的:
relatives_names = [
"Toshiaki",
"Juliana",
"Yuji",
"Bruno",
"Kaio"
]
print(relatives_names[4]) # Kaio
它的原理跟存整數一樣,很友好。
我們只學習了串列的索引是如何工作的,我還需要告訴你如何向串列的資料結構中新增一個元素(向串列中新增一個專案)。
最常用的向串列中新增新資料的方法是拼接。我們來看一下它是如何使用的:
bookshelf = []
bookshelf.append("The Effective Engineer")
bookshelf.append("The 4 Hour Work Week")
print(bookshelf[0]) # The Effective Engineer
print(bookshelf[1]) # The 4 Hour Work Week
拼接超級簡單,你僅需要把一個元素(比如“有效的機器”)作為拼接引數。
好了,關於串列的知識這些就夠了,讓我們來看一下其它的資料結構。
字典:Key-Value 資料結構
現在我們知道 List 是有索引的整型數字集合。但如果我們不像使用整型數字作為索引呢?我們可以用其他的一些資料結構,比如數字、字串或者其他型別的索引。
讓我們學習下字典這種資料結構。字典是一個鍵值對的集合。字典差不多長這樣:
dictionary_example = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
Key 是指向 value 的索引。我們如何訪問字典中的 value 呢?你應該猜到了,那就是使用 key 。 我們試一下:
dictionary_tk = {
"name": "Leandro",
"nickname": "Tk",
"nationality": "Brazilian"
}
print("My name is %s" %(dictionary_tk["name"])) # My name is Leandro
print("But you can call me %s" %(dictionary_tk["nickname"])) # But you can call me Tk
print("And by the way I'm %s" %(dictionary_tk["nationality"])) # And by the way I'm Brazilian
我們有個 key (age) value (24),使用字串作為 key 整型作為 value 。
我建立了一個關於我的字典,其中包含我的名字、暱稱和國籍。這些屬性是字典中的 key 。
就像我們學過的使用索引訪問 list 一樣,我們同樣使用索引(在字典中 key 就是索引)來訪問儲存在字典中的 value 。
正如我們使用 list 那樣,讓我們學習下如何向字典中新增元素。字典中主要是指向 value 的 key 。當我們新增元素的時候同樣如此:
dictionary_tk = {
"name": "Leandro",
"nickname": "Tk",
"nationality": "Brazilian",
"age": 24
}
print("My name is %s" %(dictionary_tk["name"])) # My name is Leandro
print("But you can call me %s" %(dictionary_tk["nickname"])) # But you can call me Tk
print("And by the way I'm %i and %s" %(dictionary_tk["age"], dictionary_tk["nationality"])) # And by the way I'm Brazilian
我們只需要將一個字典中的一個 key 指向一個 value 。沒什麼難的,對吧?
迭代:透過資料結構進行迴圈
跟我們在 Python 基礎中學習的一樣,List 迭代十分簡單。我們 Python 開發者通常使用 For 迴圈。我們試試看:
bookshelf = [
"The Effective Engineer",
"The 4 hours work week",
"Zero to One",
"Lean Startup",
"Hooked"
]
for book in bookshelf:
print(book)
對於在書架上的每本書,我們列印( 可以做任何操作 )到控制臺上。超級簡單和直觀吧。這就是 Python 的美妙之處。
對於雜湊資料結構,我們同樣可以使用 for 迴圈,不過我們需要使用 key 來進行:
dictionary = { "some_key": "some_value" }
for key in dictionary:
print("%s --> %s" %(key, dictionary[key]))
# some_key --> some_value
上面是如何在字典中使用 For 迴圈的例子。對於字典中的每個 key ,我們打印出 key 和 key 所對應的 value 。
另一種方式是使用 iteritems 方法。
dictionary = { "some_key": "some_value" }
for key, value in dictionary.items():
print("%s --> %s" %(key, value))
# some_key --> some_value
我們命名兩個引數為 key 和 value ,但是這不是必要的。我們可以隨意命名。我們看下:
dictionary_tk = {
"name": "Leandro",
"nickname": "Tk",
"nationality": "Brazilian",
"age": 24
}
for attribute, value in dictionary_tk.items():
print("My %s is %s" %(attribute, value))
# My name is Leandro
# My nickname is Tk
# My nationality is Brazilian
# My age is 24
可以看到我們使用了 attribute 作為字典中 key 的引數,這與使用 key 命名具有同樣的效果。真是太棒了!
類&物件
一些理論:
物件是對現實世界物體的表示,如汽車、狗或腳踏車。 這些物件有兩個共同的主要特徵: 資料和 行為 。
汽車有 資料 ,如車輪的數量,車門的數量和座位的空間,並且它們可以表現出其行為:它們可以加速,停止,顯示剩餘多少燃料,以及許多其他的事情。
我們將 資料 看作是面向物件程式設計中的屬性和行為。 又表示為:
資料→ 屬性和行為 → 方法
而 類 是建立單個物件的藍圖。 在現實世界中,我們經常發現許多相同型別的物件。 比如說汽車。 所有的汽車都有相同的構造和模型(都有一個引擎,輪子,門等)。每輛車都是由同一套藍圖構造成的,並具有相同的元件。
Python 面向物件程式設計樣式:ON
Python,作為一種面向物件程式語言,存在這樣的概念: 類 和 物件 。
一個類是一個藍圖,是物件的模型。
那麼,一個類是一個模型,或者是一種定義 屬性 和 行為 的方法(正如我們在理論部分討論的那樣)。舉例來說,一個車輛 類 有它自己的 屬性 來定義這個 物件 是個什麼樣的車輛。一輛車的屬性有輪子數量,能源型別,座位容量和最大時速這些。
考慮到這一點,讓我們來看看 Python 的 類 的語法:
class Vehicle:
pass
上邊的程式碼,我們使用 class 陳述句 來定義一個類。是不是很容易?
物件是一個 類 的實體化,我們可以透過類名來進行實體化。
car = Vehicle()
print(car) # <__main__.vehicle instance="" at="" class="hljs-default-number" style="color: rgb(209, 154, 102);background: rgba(0, 0, 0, 0);display: inline;width: 47px;text-decoration: none solid rgb(209, 154, 102);font-weight: 400;font-style: normal;">0x7fb1de6c2638>
在這裡,car 是類 Vehicle 的物件(或者實體化)。
記得車輛 類 有四個 屬性 :輪子的數量,油箱型別,座位容量和最大時速。當我們新建一個車輛 物件 時要設定所有的 屬性 。所以在這裡,我們定義一個 類 在它初始化的時候接受引數:
class Vehicle:
def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.type_of_tank = type_of_tank
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity
這個 init 方法 。我們稱之為建構式。因此當我們在建立一個車輛 物件 時,可以定義這些 屬性 。想象一下,我們喜歡 Tesla Model S ,所以我們想建立一個這種型別的 物件。 它有四個輪子,使用電能源,五座並且最大時時速是250千米(155英里)。我們開始建立這樣一個 物件 :
tesla_model_s = Vehicle(4, 'electric', 5, 250)
四輪+電能源+五座+最大時速250千米。
所有的屬性已經設定了。但我們該如何訪問這些屬性值呢?我們給物件傳送訊息以向其請求該值。我們稱之為方法。它是物件的行為。讓我們實現它:
class Vehicle:
def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.type_of_tank = type_of_tank
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity
def number_of_wheels(self):
return self.number_of_wheels
def set_number_of_wheels(self, number):
self.number_of_wheels = number
這是兩個方法number_of_wheels和set_number_of_wheels的實現。我們將其稱為getter & setter。因為第一個函式是獲取屬性值,第二個函式是給屬性設定新的值。
在Python中,我們可以使用@property (修飾符)來定義getters和setters。讓我們看看實際程式碼:
class Vehicle:
def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.type_of_tank = type_of_tank
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity
@property
def number_of_wheels(self):
return self.number_of_wheels
@number_of_wheels.setter
def number_of_wheels(self, number):
self.number_of_wheels = number
並且我們可以將這些方法作為屬性使用:
tesla_model_s = Vehicle(4, 'electric', 5, 250)
print(tesla_model_s.number_of_wheels) # 4
tesla_model_s.number_of_wheels = 2 # setting number of wheels to 2
print(tesla_model_s.number_of_wheels) # 2
這和方法定義有輕微的不同。這裡的方法是按照屬性執行的。例如當我們設定新的輪胎數目時,我們並不將這兩個看做引數,而是將數值2設定給number_of_wheels。這是編寫python風格的getter和setter程式碼的一種方式。
但我們也可以將該方法用於其他事項,例如“make_noise”方法。讓我們看看:
class Vehicle:
def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.type_of_tank = type_of_tank
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity
def make_noise(self):
print('VRUUUUUUUM')
當我們呼叫此方法時,它僅僅傳回一個字串“VRRRRUUUUM.”
tesla_model_s = Vehicle(4, 'electric', 5, 250)
tesla_model_s.make_noise() # VRUUUUUUUM
封裝: 隱藏資訊
封裝是一種限制直接訪問物件資料和方法的機制。但與此同時,它使得在資料上操作更簡單(物件的方法)。
“封裝可被用於隱藏數據成員和成員函式。按照這個定義,封裝意味著 物件的內部表示一般在物件定義的外部檢視中隱藏。” — Wikipedia
物件的所有內部表示都對外部隱藏了。只有物件本身可以與其內部資料互動。
首先,我們需要理解公開的、非公開的實體變數和方法的工作原理。
公共實體變數
對於 Python 類,我們可以在我們的建構式方法中初始化一個公共實體變數。讓我們看看這個:
在這個構造方法中:
class Person:
def __init__(self, first_name):
self.first_name = first_name
在這裡,我們將 first_name 值作為引數應用於公共實體變數。
tk = Person('TK')
print(tk.first_name) # => TK
在類中:
class Person:
first_name = 'TK'
在這裡,我們不需要將 first_name 作為引數,所有的實體物件都有一個用 TK 初始化的類屬性。
tk = Person()
print(tk.first_name) # => TK
太酷了,現在我們已經瞭解到,我們可以使用公共實體變數和類屬性。關於公共部分的另一個有趣的事情是我們可以管理變數值。我的意思是什麼呢?我們的物件可以管理它的變數值:Get 和 Set 變數值。
還是在 Person 類中,我們想為它的 first_name 變數設定另一個值:
tk = Person('TK')
tk.first_name = 'Kaio'
print(tk.first_name) # => Kaio
這就可以了,我們只是為 first_name 實體變數設定另一個值(kaio),並更新了值。就這麼簡單。因為這是一個公共變數,我們是可以這麼做的。
Non-public實體變數
這裡我們並沒有使用術語“private”,因為在Python中所有屬性都不是真的私有的(沒有通常不必要的工作量)。 — PEP 8
作為 public instance variable(公共實體變數),我們可以在構造方法或類內部定義 non-public instance variable (非公共實體變數)。語法上的區別是:對於 non-public instance variables (非公共實體變數),在變數名前使用下劃線(_)。
“除了從物件內部外無法被訪問的‘Private’實體變數在Python中並不存在。然而,這裡有一個多數Python程式碼都會遵守的慣例:使用下劃線作為字首的命名(例如 _spam)應該被認為是API的非公開部分(不管是函式、方法還是資料成員)” — Python軟體基礎
這裡是示例程式碼:
class Person:
def __init__(self, first_name, email):
self.first_name = first_name
self._email = email
你看到了email變數了嗎?這就是我們如何定義非公共變數的方法:
tk = Person('TK', 'tk@mail.com')
print(tk._email) # tk@mail.com
我們可以訪問並更新它。非公共變數僅僅是一個慣用法,並且應該被當做API的非公共部分。
所以我們使用一個在類定義內部的方法來實現該功能。讓我們實現兩個方法(email 和update_email)以加深理解:
class Person:
def __init__(self, first_name, email):
self.first_name = first_name
self._email = email
def update_email(self, new_email):
self._email = new_email
def email(self):
return self._email
現在我們可以使用這兩個方法來更新及訪問非公開變數了。示例如下:
tk = Person('TK', 'tk@mail.com')
print(tk.email()) # => tk@mail.com
tk._email = 'new_tk@mail.com'
print(tk.email()) # => tk@mail.com
tk.update_email('new_tk@mail.com')
print(tk.email()) # => new_tk@mail.com
-
我們使用first_name TK和email tk@mail.com初始化了一個新物件
-
使用方法訪問非公開變數email並輸出它
-
嘗試在類外部設定一個新的email
-
我們需要將非公開變數視為API的非公開部分
-
使用我們的實體方法來更新非公開變數
-
成功!我們使用輔助方法在類內部更新了它。
公共方法
對於公共方法,我們也可以在類中使用它們:
class Person:
def __init__(self, first_name, age):
self.first_name = first_name
self._age = age
def show_age(self):
return self._age
讓我們來測試一下:
tk = Person('TK', 25)
print(tk.show_age()) # => 25
很好 – 我們在類中使用它沒有任何問題。
非公共方法
但是用非公開的方法,我們無法做到這一點。 如果我們想實現相同的 Person 類,現在使用有下劃線(_)的 show_age 非公共方法。
class Person:
def __init__(self, first_name, age):
self.first_name = first_name
self._age = age
def _show_age(self):
return self._age
現在,我們將嘗試用我們的物件來呼叫這個非公共的方法:
我們可以訪問和更新它。 非公共的方法只是一個慣例,應該被視為API的非公開部分。
以下是我們如何使用它的一個例子:
class Person:
def __init__(self, first_name, age):
self.first_name = first_name
self._age = age
def show_age(self):
return self._get_age()
def _get_age(self):
return self._age
tk = Person('TK', 25)
print(tk.show_age()) # => 25
這裡有一個 _get_age 非公共方法和一個 show_age 公共方法。 show_age 可以被我們的物件(不在我們的類中)使用,而 _get_age 只用在我們的類定義裡面使用(在 show_age 方法裡面)。 但是同樣的,這樣的做法通常是慣例。
封裝小結
透過封裝,我們可以確保物件的內部表示是對外部隱藏的。
繼承:行為和特徵
某些物體有一些共同之處:它們的行為和特徵。
例如,我繼承了我父親的一些特徵和行為。我繼承了他的眼睛和頭髮的特徵,以及他的急躁和內向的行為。
在面向物件程式設計中,類可以繼承另一個類的共同特徵(資料)和行為(方法)。
我們來看另一個例子,並用 Python 實現它。
想象一下汽車。車輪數量,座位容量和最大速度都是一輛車的屬性。我們可以說 ElectricCar 類從普通的 Car 類繼承了這些相同的屬性。
class Car:
def __init__(self, number_of_wheels, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity
我們 Car 類的實現:
my_car = Car(4, 5, 250)
print(my_car.number_of_wheels)
print(my_car.seating_capacity)
print(my_car.maximum_velocity)
在 Python 中,我們將父類作為子的引數來進行繼承。 ElectricCar 類可以繼承我們的 Car 類。
class ElectricCar(Car):
def __init__(self, number_of_wheels, seating_capacity, maximum_velocity):
Car.__init__(self, number_of_wheels, seating_capacity, maximum_velocity)
就這麼簡單。我們不需要實現任何其他方法,因為這個類已經完成了父類的繼承(繼承自 Car 類)。我們來證明一下:
my_electric_car = ElectricCar(4, 5, 250)
print(my_electric_car.number_of_wheels) # => 4
print(my_electric_car.seating_capacity) # => 5
print(my_electric_car.maximum_velocity) # => 250
乾的漂亮。
總結
我們已經學到了很多關於 Python 的基礎知識:
-
Python 變數是如何工作的
-
Python 條件陳述句是如何工作的
-
Python 迴圈( while 和 for )是如何工作的
-
如何使用連結串列:Collection |Array
-
字典式鍵值集合
-
我們如何遍歷這些資料結構
-
物件和類
-
作為物件資料的屬性
-
作為物件行為的方法
-
使用 Python getter/setter 以及屬性修飾器
-
封裝:隱藏資訊
-
繼承:行為和特徵
恭喜! 你完成了這個關於 Python 的密集的知識點。
源 | medium.com
譯 | OSC
更多Python好文請點選【閱讀原文】哦
↓↓↓