本文是基於黑馬程序員2018年的Python基礎班的內容編寫的,以2018年的資料爲藍本,2016年的資料爲補充,還參考了一些網上的教程,旨在更好地總結Python基礎知識,力求簡明扼要,以供實戰演練時可以快速查詢遺忘的知識點。全文分爲兩大部分,分別是Python基礎語法和麪向對象。html
Python 的創始人爲吉多·範羅蘇姆(Guido van Rossum)。python
Python 的設計目標:git
- 一門簡單直觀的語言並與主要競爭者同樣強大
- 開源,以便任何人均可覺得它作貢獻
- 代碼像純英語那樣容易理解
- 適用於短時間開發的平常任務
Python 的設計哲學:程序員
- 優雅、明確、簡單
Python 開發者的哲學是:用一種方法,最好是隻有一種方法來作一件事面試
Python 是徹底面向對象的語言,在 Python 中一切皆對象。算法
可擴展性:若是須要一段關鍵代碼運行得更快或者但願某些算法不公開,能夠把這部分程序用
C
或C++
編寫,而後在Python
程序中使用它們。shell
執行 Python 程序的三種方式: 解釋器、交互式運行、IDE運行編程
Python 是一個格式很是嚴格的程序設計語言。 python 2.x 默認不支持中文。ubuntu
ASCII
字符只包含256
個字符,不支持中文
爲了照顧現有的程序,官方提供了一個過渡版本 —— Python 2.6。設計模式
提示:若是開發時,沒法當即使用 Python 3.0(還有極少的第三方庫不支持 3.0 的語法),建議
- 先使用
Python 3.0
版本進行開發- 而後使用
Python 2.6
、Python 2.7
來執行,而且作一些兼容性的處理
IPython 是一個 python 的 交互式 shell,比默認的 python shell
好用得多,它支持 bash shell
命令,適合於學習/驗證 Python 語法或者局部代碼。
集成開發環境(IDE
,Integrated Development Environment)—— 集成了開發軟件須要的全部工具,通常包括如下工具:
PyCharm 的 配置信息 是保存在 用戶家目錄下 的 .PyCharmxxxx.x
目錄下的,xxxx.x
表示當前使用的 PyCharm 的版本號
$ rm -r ~/.PyCharm2016.3
複製代碼
$ tar -zxvf pycharm-professional-2017.1.3.tar.gz
複製代碼
/opt
目錄下,能夠方便其餘用戶使用
/opt
目錄用戶存放給主機額外安裝的軟件
$ sudo mv pycharm-2017.1.3/ /opt/
複製代碼
$ cd /opt/pycharm-2017.1.3/bin
複製代碼
$ ./pycharm.sh
複製代碼
Create the entry for all users
快捷方式文件 /usr/share/applications/jetbrains-pycharm.desktop
在
ubuntu
中,應用程序啓動的快捷方式一般都保存在/usr/share/applications
目錄下
要卸載 PyCharm 只須要作如下兩步工做:
$ sudo rm -r /opt/pycharm-2016.3.1/
複製代碼
$ rm -r ~/.PyCharm2016.3/
複製代碼
若是再也不使用 PyCharm 還須要將
/usr/share/applications/
下的jetbrains-pycharm.desktop
刪掉
PyCharm
中,要想讓哪個 Python
程序可以執行,必須首先經過 鼠標右鍵的方式執行 一下#
開頭,#
右邊的全部東西都被當作說明文字,而不是真正要執行的程序,只起到輔助說明做用print("hello python") # 輸出 `hello python`
複製代碼
爲了保證代碼的可讀性,
#
後面建議先添加一個空格,而後再編寫相應的說明文字;爲了保證代碼的可讀性,註釋和代碼之間 至少要有 兩個空格。
""" 這是一個多行註釋 在多行註釋之間,能夠寫不少不少的內容…… """
print("hello python")
複製代碼
提示:
Python
官方提供有一系列 PEP(Python Enhancement Proposals) 文檔,其中第 8 篇文檔專門針對 Python 的代碼格式 給出了建議,也就是俗稱的 PEP 8:
是完成基本的算術運算使用的符號,用來處理四則運算,而「+」和「*」還能夠用來處理字符串。
運算符 | 描述 | 實例 |
---|---|---|
+ | 加 | 10 + 20 = 30 |
- | 減 | 10 - 20 = -10 |
* | 乘 | 10 * 20 = 200 |
/ | 除 | 10 / 20 = 0.5 |
// | 取整除 | 返回除法的整數部分(商) 9 // 2 輸出結果 4 |
% | 取餘數 | 返回除法的餘數 9 % 2 = 1 |
** | 冪 | 又稱次方、乘方,2 ** 3 = 8 |
運算符 | 描述 |
---|---|
== | 檢查兩個操做數的值是否 相等,若是是,則條件成立,返回 True |
!= | 檢查兩個操做數的值是否 不相等,若是是,則條件成立,返回 True |
> | 檢查左操做數的值是否 大於 右操做數的值,若是是,則條件成立,返回 True |
< | 檢查左操做數的值是否 小於 右操做數的值,若是是,則條件成立,返回 True |
>= | 檢查左操做數的值是否 大於或等於 右操做數的值,若是是,則條件成立,返回 True |
<= | 檢查左操做數的值是否 小於或等於 右操做數的值,若是是,則條件成立,返回 True |
- Python 2.x 中判斷 不等於 還可使用
<>
運算符!=
在 Python 2.x 中一樣能夠用來判斷 不等於
=
能夠給變量賦值。在算術運算時,爲了簡化代碼的編寫,Python
還提供了一系列的 與 算術運算符 對應的 賦值運算符,注意:賦值運算符中間不能使用空格。運算符 | 描述 | 實例 |
---|---|---|
= | 簡單的賦值運算符 | c = a + b 將 a + b 的運算結果賦值爲 c |
+= | 加法賦值運算符 | c += a 等效於 c = c + a |
-= | 減法賦值運算符 | c -= a 等效於 c = c - a |
*= | 乘法賦值運算符 | c *= a 等效於 c = c * a |
/= | 除法賦值運算符 | c /= a 等效於 c = c / a |
//= | 取整除賦值運算符 | c //= a 等效於 c = c // a |
%= | 取 模 (餘數)賦值運算符 | c %= a 等效於 c = c % a |
**= | 冪賦值運算符 | c **= a 等效於 c = c ** a |
身份運算符比較兩個對象的內存位置。經常使用的有兩個身份運算符,以下所述:
運算符 | 描述 | 示例 |
---|---|---|
is | 判斷兩個標識符是否是引用同一個對象 | x is y,相似 id(x) == id(y) |
is not | 判斷兩個標識符是否是引用不一樣對象 | x is not y,相似 id(a) != id(b) |
辨析
Python成員運算符測試給定值是否爲序列中的成員。 有兩個成員運算符,以下所述:
運算符 | 描述 |
---|---|
in | 若是在指定的序列中找到一個變量的值,則返回true,不然返回false。 |
not in | 若是在指定序列中找不到變量的值,則返回true,不然返回false。 |
運算符 | 邏輯表達式 | 描述 |
---|---|---|
and | x and y | 只有 x 和 y 的值都爲 True,纔會返回 True 不然只要 x 或者 y 有一個值爲 False,就返回 False |
or | x or y | 只要 x 或者 y 有一個值爲 True,就返回 True 只有 x 和 y 的值都爲 False,纔會返回 False |
not | not x | 若是 x 爲 True,返回 False 若是 x 爲 False,返回 True |
運算符 | 描述 |
---|---|
** | 冪 (最高優先級) |
* / % // | 乘、除、取餘數、取整除 |
+ - | 加法、減法 |
<= < > >= | 比較運算符 |
== != | 等於運算符 |
= %= /= //= -= += *= **= | 賦值運算符 |
is is not | 身份運算符 |
in not in | 成員運算符 |
not or and | 邏輯運算符 |
# 1. 確認解釋器所在位置
$ which python
# 2. 查看 python 文件大小(只是一個軟連接)
$ ls -lh /usr/bin/python
# 3. 查看具體文件大小
$ ls -lh /usr/bin/python2.7
複製代碼
變量名 = 值
複製代碼
使用交互式方式,若是要查看變量內容,直接輸入變量名便可,不須要使用
Python
中定義變量是 不須要指定類型(在其餘不少高級語言中都須要),Python 能夠根據 =
等號右側的值,自動推導出變量中存儲數據的類型int
):Python3中的全部整數都表示爲長整數。 所以,長整數沒有單獨的數字類型。float
)bool
) :真 True
非 0 數
—— 非零即真,假 False
0
。complex
):複數是由x + yj表示的有序對的實數浮點數組成,其中x和y是實數,j是虛數單位。str
):加號(+
)是字符串鏈接運算符,星號(*
)是重複運算符。list
)tuple
)dict
)提示:在 Python 2.x 中,整數 根據保存數值的長度還分爲:
int
(整數)long
(長整數)
type
函數能夠查看一個變量的類型In [1]: type(name)
複製代碼
bool
型,在計算時
True
對應的數字是 1
False
對應的數字是 0
+
拼接字符串*
重複拼接相同的字符串input
函數從鍵盤等待用戶的輸入字符串變量 = input("提示信息:")
複製代碼
函數 | 說明 |
---|---|
int(x) | 將 x 轉換爲一個整數 |
float(x) | 將 x 轉換到一個浮點數 |
str(x) | 將對象x轉換爲字符串表示形式 |
tuple(s) | 將s轉換爲元組 |
list(s) | 將s轉換爲列表 |
price = float(input("請輸入價格:"))
複製代碼
%
被稱爲 格式化操做符,專門用於處理字符串中的格式
%
的字符串,被稱爲 格式化字符串%
和不一樣的 字符 連用,不一樣類型的數據 須要使用 不一樣的格式化字符格式化字符 | 含義 |
---|---|
%s | 字符串 |
%d | 有符號十進制整數,%06d 表示輸出的整數顯示位數,不足的地方使用 0 補全 |
%f | 浮點數,%.2f 表示小數點後只顯示兩位 |
%% | 輸出 % |
print("格式化字符串" % 變量1)
print("格式化字符串" % (變量1, 變量2...))
複製代碼
標示符就是程序員定義的 變量名、函數名
- 標示符能夠由 字母、下劃線 和 數字 組成
- 不能以數字開頭
- 不能與關鍵字重名
關鍵字 就是在
Python
內部已經使用的標識符
- 關鍵字 具備特殊的功能和含義
- 開發者 不容許定義和關鍵字相同的名字的標識符
- 經過如下命令能夠查看
Python
中的關鍵字In [1]: import keyword In [2]: print(keyword.kwlist) 複製代碼
命名規則 能夠被視爲一種 慣例,並沒有絕對與強制 目的是爲了 增長代碼的識別和可讀性 注意
Python
中的 標識符 是 區分大小寫的
=
的左右應該各保留一個空格_
下劃線 鏈接,例如:first_name
、last_name
、qq_number
、qq_password
。固然,還有駝峯命名法: 小駝峯式命名法:第一個單詞以小寫字母開始,後續單詞的首字母大寫,例如:firstName
、lastName
。 大駝峯式命名法,每個單詞的首字母都採用大寫字母,例如:FirstName
、LastName
、CamelCase
。
在 Python
中,全部 非數字型變量 都支持如下特色: 1. 都是一個 序列 sequence
,也能夠理解爲 容器 2. 取值 []
3. 遍歷 for in
4. 計算長度len
、最大/最小值max/min
、比較、刪除del
5. 連接 +
和 重複 *
6. 切片
List
(列表) 是 Python
中使用 最頻繁 的數據類型,在其餘語言中一般叫作 數組,專門用於存儲 一串 信息,列表用 []
定義,數據 之間使用 ,
分隔,列表的 索引 從 0
開始。索引 就是數據在 列表 中的位置編號,索引 又能夠被稱爲 下標 注意:從列表中取值時,若是 超出索引範圍,程序會報錯
name_list = ["zhangsan", "lisi", "wangwu"]
複製代碼
del
關鍵字(delete
) 一樣能夠刪除列表中元素del
關鍵字本質上是用來 將一個變量從內存中刪除的del
關鍵字將變量從內存中刪除,後續的代碼就不能再使用這個變量了In [1]: l = [1,2,3,4]
In [2]: del l[1]
In [3]: l[1]
Out[3]: 3
複製代碼
在平常開發中,要從列表刪除數據,建議 使用列表提供的方法
函數名(參數)
複製代碼
函數須要死記硬背
對象.方法名(參數)
複製代碼
在變量後面輸入
.
,而後選擇針對這個變量要執行的操做,記憶起來比函數要簡單不少
遍歷 就是 從頭至尾 依次 從 列表 中獲取數據,在 循環體內部 針對 每個元素,執行相同的操做。
在 Python 中爲了提升列表的遍歷效率,使用 for
就可以實現迭代遍歷。
# for 循環內部使用的變量 in 列表
for name in name_list:
循環內部針對列表元素進行操做
print(name)
複製代碼
Tuple
(元組)與列表相似,不一樣之處在於元組的 元素不能修改
Python
開發中,有特定的應用場景
,
分隔()
定義,元組的 索引 從 0
開始,索引 就是數據在 元組 中的位置編號。info_tuple = ("zhangsan", 18, 1.75)
複製代碼
建立空元組:
info_tuple = ()
複製代碼
元組中 只包含一個元素 時,須要 在元素後面添加逗號:
info_tuple = (50, )
複製代碼
- 在 Python 中,可使用
for
循環遍歷全部非數字型類型的變量:列表、元組、字典 以及 字符串- 提示:在實際開發中,除非 可以確認元組中的數據類型,不然針對元組的循環遍歷需求並非不少
- 在開發中,更多的應用場景是:
- 函數的 參數 和 返回值,一個函數能夠接收 任意多個參數,或者 一次返回多個數據
- 格式字符串,格式化字符串後面的
()
本質上就是一個元組- 讓列表不能夠被修改,以保護數據安全
list
函數能夠把元組轉換成列表list(元組)
複製代碼
tuple
函數能夠把列表轉換成元組tuple(列表)
複製代碼
dict
(字典) 是 除列表之外 Python 之中 最靈活 的數據類型。 字典一樣能夠用來 存儲多個數據,一般用於存儲 描述一個 物體 的相關信息
{}
定義。,
分隔:
key
是索引value
是數據:
分隔xiaoming = {"name": "小明",
"age": 18,
"gender": True,
"height": 1.75}
複製代碼
# for 循環內部使用的 `key 的變量` in 字典
for k in xiaoming:
print("%s: %s" % (k, xiaoming[k]))
複製代碼
提示:在實際開發中,因爲字典中每個鍵值對保存數據的類型是不一樣的,因此針對字典的循環遍歷需求並非不少
for in
遍歷 字典物體
的相關信息 —— 描述更復雜的數據信息card_list = [{"name": "張三",
"qq": "12345",
"phone": "110"},
{"name": "李四",
"qq": "54321",
"phone": "10086"}
]
複製代碼
"
或者 一對單引號 '
定義一個字符串
\"
或者 \'
作字符串的轉義,可是在實際開發中:
"
,可使用 '
定義字符串'
,可使用 "
定義字符串for
循環遍歷 字符串中每個字符大多數編程語言都是用
"
來定義字符串
string = "Hello Python"
for c in string:
print(c)
複製代碼
提示:在 python 中對字符串操做,內置提供的方法足夠多,使得在開發時,可以針對字符串進行更加靈活的操做!應對更多的開發需求!
方法 | 說明 |
---|---|
string.isspace() | 若是 string 中只包含空格,則返回 True |
string.isalnum() | 若是 string 至少有一個字符而且全部字符都是字母或數字則返回 True |
string.isalpha() | 若是 string 至少有一個字符而且全部字符都是字母則返回 True |
string.isdecimal() | 若是 string 只包含數字則返回 True,全角數字 |
string.isdigit() | 若是 string 只包含數字則返回 True,全角數字 、⑴ 、\u00b2 |
string.isnumeric() | 若是 string 只包含數字則返回 True,全角數字 ,漢字數字 |
string.istitle() | 若是 string 是標題化的(每一個單詞的首字母大寫)則返回 True |
string.islower() | 若是 string 中包含至少一個區分大小寫的字符,而且全部這些(區分大小寫的)字符都是小寫,則返回 True |
string.isupper() | 若是 string 中包含至少一個區分大小寫的字符,而且全部這些(區分大小寫的)字符都是大寫,則返回 True |
方法 | 說明 |
---|---|
string.startswith(str) | 檢查字符串是不是以 str 開頭,是則返回 True |
string.endswith(str) | 檢查字符串是不是以 str 結束,是則返回 True |
string.find(str, start=0, end=len(string)) | 檢測 str 是否包含在 string 中,若是 start 和 end 指定範圍,則檢查是否包含在指定範圍內,若是是返回開始的索引值,不然返回 -1 |
string.rfind(str, start=0, end=len(string)) | 相似於 find(),不過是從右邊開始查找 |
string.index(str, start=0, end=len(string)) | 跟 find() 方法相似,不過若是 str 不在 string 會報錯 |
string.rindex(str, start=0, end=len(string)) | 相似於 index(),不過是從右邊開始 |
string.replace(old_str, new_str, num=string.count(old)) | 把 string 中的 old_str 替換成 new_str,若是 num 指定,則替換不超過 num 次 |
方法 | 說明 |
---|---|
string.capitalize() | 把字符串的第一個字符大寫 |
string.title() | 把字符串的每一個單詞首字母大寫 |
string.lower() | 轉換 string 中全部大寫字符爲小寫 |
string.upper() | 轉換 string 中的小寫字母爲大寫 |
string.swapcase() | 翻轉 string 中的大小寫 |
方法 | 說明 |
---|---|
string.ljust(width) | 返回一個原字符串左對齊,並使用空格填充至長度 width 的新字符串 |
string.rjust(width) | 返回一個原字符串右對齊,並使用空格填充至長度 width 的新字符串 |
string.center(width) | 返回一個原字符串居中,並使用空格填充至長度 width 的新字符串 |
方法 | 說明 |
---|---|
string.lstrip() | 截掉 string 左邊(開始)的空白字符 |
string.rstrip() | 截掉 string 右邊(末尾)的空白字符 |
string.strip() | 截掉 string 左右兩邊的空白字符 |
方法 | 說明 |
---|---|
string.partition(str) | 把字符串 string 分紅一個 3 元素的元組 (str前面, str, str後面) |
string.rpartition(str) | 相似於 partition() 方法,不過是從右邊開始查找 |
string.split(str="", num) | 以 str 爲分隔符拆分 string,若是 num 有指定值,則僅分隔 num + 1 個子字符串,str 默認包含 '\r', '\t', '\n' 和空格 |
string.splitlines() | 按照行('\r', '\n', '\r\n')分隔,返回一個包含各行做爲元素的列表 |
string.join(seq) | 以 string 做爲分隔符,將 seq 中全部的元素(的字符串表示)合併爲一個新的字符串 |
字符串[開始索引:結束索引:步長]
複製代碼
注意:
[開始索引, 結束索引)
=> 開始索引 <= 範圍 < 結束索引
起始
位開始,到 結束
位的前一位 結束(不包含結束位自己)1
,若是連續切片,數字和冒號均可以省略num_str = "0123456789"
# 1. 截取從 2 ~ 5 位置 的字符串
print(num_str[2:6])
# 2. 截取從 2 ~ `末尾` 的字符串
print(num_str[2:])
# 3. 截取從 `開始` ~ 5 位置 的字符串
print(num_str[:6])
# 4. 截取完整的字符串
print(num_str[:])
# 5. 從開始位置,每隔一個字符截取字符串
print(num_str[::2])
# 6. 從索引 1 開始,每隔一個取一個
print(num_str[1::2])
# 倒序切片
# -1 表示倒數第一個字符
print(num_str[-1])
# 7. 截取從 2 ~ `末尾 - 1` 的字符串
print(num_str[2:-1])
# 8. 截取字符串末尾兩個字符
print(num_str[-2:])
# 9. 字符串的逆序(面試題)
print(num_str[::-1])
複製代碼
Python 包含了如下內置函數:
函數 | 描述 | 備註 |
---|---|---|
len(item) | 計算容器中元素個數 | |
del(item) | 刪除變量 | del 有兩種方式 |
max(item) | 返回容器中元素最大值 | 若是是字典,只針對 key 比較 |
min(item) | 返回容器中元素最小值 | 若是是字典,只針對 key 比較 |
cmp(item1, item2) | 比較兩個值,-1 小於 / 0 相等 / 1 大於 | Python 3.x 取消了 cmp 函數 |
注意:字符串 比較符合如下規則: "0" < "A" < "a"。
描述 | Python 表達式 | 結果 | 支持的數據類型 |
---|---|---|---|
切片 | "0123456789"[::-2] | "97531" | 字符串、列表、元組 |
運算符 | Python 表達式 | 結果 | 描述 | 支持的數據類型 |
---|---|---|---|---|
+ | [1, 2] + [3, 4] | [1, 2, 3, 4] | 合併 | 字符串、列表、元組 |
* | ["Hi!"] * 4 | ['Hi!', 'Hi!', 'Hi!', 'Hi!'] | 重複 | 字符串、列表、元組 |
in | 3 in (1, 2, 3) | True | 元素是否存在 | 字符串、列表、元組、字典 |
not in | 4 not in (1, 2, 3) | True | 元素是否不存在 | 字符串、列表、元組、字典 |
> >= == < <= | (1, 2, 3) < (2, 2, 3) | True | 元素比較 | 字符串、列表、元組 |
注意
in
在對 字典 操做時,判斷的是 字典的鍵in
和 not in
被稱爲 成員運算符for 循環
的語法以下:for 變量 in 集合:
循環體代碼
else:
沒有經過 break 退出循環,循環結束後,會執行的代碼
複製代碼
應用場景:
- 變量 和 數據 都是保存在 內存 中的
- 在 Python 中 函數 的 參數傳遞 以及 返回值 都是靠 引用 傳遞的
在 Python 中:變量 和 數據 是分開存儲的,數據 保存在內存中的一個位置,變量 中保存着數據在內存中的地址,就叫作 引用,使用 id()
函數能夠查看變量中保存數據所在的 內存地址。
注意:若是變量已經被定義,當給一個變量賦值的時候,本質上是 修改了數據的引用
- 變量 再也不 對以前的數據引用
- 變量 改成 對新賦值的數據引用
在 Python 中,變量的名字相似於 便籤紙 貼在 數據 上:
a
,而且賦值爲 1
代碼 | 圖示 |
---|---|
a = 1 |
a
賦值爲 2
代碼 | 圖示 |
---|---|
a = 2 |
b
,而且將變量 a
的值賦值給 b
代碼 | 圖示 |
---|---|
b = a |
在 Python
中,函數的 實參/返回值 都是是靠 引用 來傳遞來的
def test(num):
print("-" * 50)
print("%d 在函數內的內存地址是 %x" % (num, id(num)))
result = 100
print("返回值 %d 在內存中的地址是 %x" % (result, id(result)))
print("-" * 50)
return result
a = 10
print("調用函數前 內存地址是 %x" % id(a))
r = test(a)
print("調用函數後 實參內存地址是 %x" % id(a))
print("調用函數後 返回值內存地址是 %x" % id(r))
複製代碼
不可變類型,內存中的數據不容許被修改:
int
, bool
, float
, complex
, long(2.x)
str
tuple
可變類型,內存中的數據能夠被修改:
list
dict
注意:字典的
key
只能使用不可變類型的數據
注意
(hash)
hash(o)
的函數:接收一個 不可變類型 的數據做爲 參數,返回 結果是一個 整數。哈希
是一種 算法,其做用就是提取數據的 特徵碼(指紋),相同的內容 獲得 相同的結果,不一樣的內容 獲得 不一樣的結果。key
進行 hash
已決定如何在內存中保存字典的數據,以方便 後續 對字典的操做:增、刪、改、查:鍵值對的 key
必須是不可變類型數據,鍵值對的 value
能夠是任意類型的數據。提示:在其餘的開發語言中,大多 不推薦使用全局變量 —— 可變範圍太大,致使程序很差維護!
注意:函數執行時,須要處理變量時 會:
注意:函數不能直接修改全局變量的引用,若是要修改,必需要用global
聲明該變量是全局變量。
num = 10
def demo1():
print("demo1" + "-" * 50)
# global 關鍵字,告訴 Python 解釋器 num 是一個全局變量
global num
# 只是定義了一個局部變量,不會修改到全局變量,只是變量名相同而已
num = 100
print(num)
def demo2():
print("demo2" + "-" * 50)
print(num)
demo1()
demo2()
print("over")
複製代碼
注意:爲了不局部變量和全局變量出現混淆,在定義全局變量時,有些公司會有一些開發要求,例如:全局變量名前應該增長 g_
或者 gl_
的前綴。
一、if 判斷語句基本語法:
if 要判斷的條件:
條件成立時,要作的事情
……
複製代碼
注意:代碼的縮進爲一個
tab
鍵,或者 4 個空格 —— 建議使用空格
- 在 Python 開發中,Tab 和空格不要混用!
二、若是須要在 不知足條件的時候,作某些事情,該如何作呢?
if 要判斷的條件:
條件成立時,要作的事情
……
else:
條件不成立時,要作的事情
……
複製代碼
條件1 and 條件2 :兩個條件同時知足,返回 True
條件1 or 條件2:兩個條件只要有一個知足,返回 True
not 條件:非,不是
複製代碼
三、若是但願 再增長一些條件,條件不一樣,須要執行的代碼也不一樣 時,就可使用 elif
:
if 條件1:
條件1知足執行的代碼
……
elif 條件2:
條件2知足時,執行的代碼
……
elif 條件3:
條件3知足時,執行的代碼
……
else:
以上條件都不知足時,執行的代碼
……
複製代碼
注意
elif
和 else
都必須和 if
聯合使用,而不能單獨使用if
、elif
和 else
以及各自縮進的代碼,當作一個 完整的代碼塊四、在開發中,使用 if
進行條件判斷,若是但願 在條件成立的執行語句中 再 增長條件判斷,就可使用 if 的嵌套:
if 條件 1:
條件 1 知足執行的代碼
……
if 條件 1 基礎上的條件 2:
條件 2 知足時,執行的代碼
……
# 條件 2 不知足的處理
else:
條件 2 不知足時,執行的代碼
# 條件 1 不知足的處理
else:
條件1 不知足時,執行的代碼
……
複製代碼
Python
中,要使用隨機數,首先須要導入 隨機數 的 模塊 —— 「工具包」import random
複製代碼
導入模塊後,能夠直接在 模塊名稱 後面敲一個 .
而後按 Tab
鍵,會提示該模塊中包含的全部函數
random.randint(a, b)
,返回 [a, b]
之間的整數,包含 a
和 b
例如:
random.randint(12, 20) # 生成的隨機數n: 12 <= n <= 20
random.randint(20, 20) # 結果永遠是 20
random.randint(20, 10) # 該語句是錯誤的,下限必須小於上限
複製代碼
# 導入隨機工具包
# 注意:在導入工具包的時候,應該將導入的語句,放在文件的頂部
# 由於,這樣能夠方便下方的代碼,在任何須要的時候,使用工具包中的工具
import random
# 從控制檯輸入要出的拳 —— 石頭(1)/剪刀(2)/布(3)
player = int(input("請輸入您要出的拳 石頭(1)/剪刀(2)/布(3):"))
# 電腦 隨機 出拳 —— 先假定電腦只會出石頭,完成總體代碼功能
computer = random.randint(1, 3)
print("玩家選擇的拳頭是 %d - 電腦出的拳是 %d" % (player, computer))
# 比較勝負
# 1 石頭 勝 剪刀
# 2 剪刀 勝 布
# 3 布 勝 石頭
# if (()
# or ()
# or ()):
if ((player == 1 and computer == 2)
or (player == 2 and computer == 3)
or (player == 3 and computer == 1)):
print("歐耶,電腦弱爆了!")
# 平局
elif player == computer:
print("真是心有靈犀啊,再來一盤")
# 其餘的狀況就是電腦獲勝
else:
print("不服氣,咱們決戰到天明!")
複製代碼
在程序開發中,一共有三種流程方式:
while
語句基本語法:
初始條件設置 —— 一般是重複執行的 計數器
while 條件(判斷 計數器 是否達到 目標次數):
條件知足時,作的事情1
條件知足時,作的事情2
條件知足時,作的事情3
...(省略)...
處理條件(計數器 + 1)
複製代碼
因爲程序員的緣由,忘記 在循環內部 修改循環的判斷條件,致使循環持續執行,程序將陷入死循環而沒法終止!
計數器 +1 :能夠經過賦值運算符簡化代碼的編寫。 常見的計數方法有兩種,能夠分別稱爲:
1
開始)—— 更符合人類的習慣0
開始)—— 幾乎全部的程序語言都選擇從 0 開始計數所以,你們在編寫程序時,應該儘可能養成習慣:除非需求的特殊要求,不然 循環 的計數都從 0 開始
break
和continue
是專門在循環中使用的關鍵字
break
:某一條件知足時,退出循環,再也不執行後續的代碼continue
:某一條件知足時,不執行後續的代碼直接進入下一次循環break
和 continue
只針對 當前所在循環 有效while
嵌套就是:while
裏面還有 while
,每一次循環中還要作完一個循環。while 條件 1:
條件知足時,作的事情1
條件知足時,作的事情2
條件知足時,作的事情3
...(省略)...
while 條件 2:
條件知足時,作的事情1
條件知足時,作的事情2
條件知足時,作的事情3
...(省略)...
處理條件 2
處理條件 1
複製代碼
示例:
""" 打印 9 行小星星: * ** *** **** ***** ****** ******* ******** ********* """
# 定義起始行
row = 1
# 最大打印 9 行
while row <= 9:
# 定義起始列
col = 1
# 最大打印 row 列
while col <= row:
# end = "",表示輸出結束後,不換行
# "\t" 能夠在控制檯輸出一個製表符,協助在輸出文本時對齊
print("%d * %d = %d" % (col, row, row * col), end="\t")
# 列數 + 1
col += 1
# 一行打印完成的換行
print("")
# 行數 + 1
row += 1
複製代碼
\t
在控制檯輸出一個 製表符,協助在輸出文本時 垂直方向 保持對齊\n
在控制檯輸出一個 換行符製表符 的功能是在不使用表格的狀況下在 垂直方向 按列對齊文本
轉義字符 | 描述 |
---|---|
\\ | 反斜槓符號 |
\' | 單引號 |
\" | 雙引號 |
\n | 換行 |
\t | 橫向製表符 |
\r | 回車 |
所謂函數,就是把 具備獨立功能的代碼塊 組織爲一個小模塊,在須要的時候 調用。在開發程序時,使用函數能夠提升編寫的效率以及代碼的 重用,函數的使用包含兩個步驟: 1. 定義函數 —— 封裝 獨立的功能 2. 調用函數 —— 享受 封裝 的成果
def 函數名():
函數封裝的代碼
……
複製代碼
函數名()
便可完成對函數的調用。PyCharm 的調試工具:
- F8 Step Over 能夠單步執行代碼,會把函數調用看做是一行代碼直接執行
- F7 Step Into 能夠單步執行代碼,若是是函數,會進入函數內部
CTRL + Q
能夠查看函數的說明信息。注意:由於 函數體相對比較獨立,函數定義的上方,應該和其餘代碼(包括註釋)保留 兩個空行
,
分隔。def sum_2_num(num1, num2):
result = num1 + num2
print("%d + %d = %d" % (num1, num2, result))
sum_2_num(50, 20)
複製代碼
問題 1:在函數內部,針對參數使用 賦值語句,會不會影響調用函數時傳遞的 實參變量? —— 不會!
問題 2:若是傳遞的參數是 可變類型,在函數內部,使用 方法 修改了數據的內容,一樣會影響到外部的數據,例如列表變量調用
+=
本質上是在執行列表變量的extend
方法。
定義函數時,能夠給 某個參數 指定一個默認值,具備默認值的參數就叫作 缺省參數,* 調用函數時,若是沒有傳入 缺省參數 的值,則在函數內部使用定義函數時指定的 參數默認值,將常見的值設置爲參數的缺省值,從而 簡化函數的調用。例如:對列表排序的方法:
gl_num_list = [6, 3, 9]
# 默認就是升序排序,由於這種應用需求更多
gl_num_list.sort()
print(gl_num_list)
# 只有當須要降序排序時,才須要傳遞 `reverse` 參數
gl_num_list.sort(reverse=True)
print(gl_num_list)
複製代碼
def print_info(name, gender=True):
gender_text = "男生"
if not gender:
gender_text = "女生"
print("%s 是 %s" % (name, gender_text))
複製代碼
提示
注意
有時可能須要 一個函數 可以處理的參數 個數 是不肯定的,這個時候,就可使用 多值參數。
python
中有 兩種 多值參數:
*
能夠接收 元組**
能夠接收 字典*args
—— 存放 元組 參數,前面有一個 *
**kwargs
—— 存放 字典 參數,前面有兩個 **
def demo(num, *args, **kwargs):
print(num)
print(args)
print(kwargs)
demo(1, 2, 3, 4, 5, name="小明", age=18, gender=True)
print("-"*20)
demo(1,(2,3,4,5),{"name":"小明", "age":18, "gender":True})
print("-"*20)
demo(1,(2,3,4,5), name="小明", age=18, gender=True)
複製代碼
args
kwargs
*
*
def demo(*args, **kwargs):
print(args)
print(kwargs)
# 須要將一個元組變量/字典變量傳遞給函數對應的參數
gl_nums = (1, 2, 3)
gl_xiaoming = {"name": "小明", "age": 18}
# 會把 num_tuple 和 xiaoming 做爲元組傳遞個 args
# demo(gl_nums, gl_xiaoming)
demo(*gl_nums, **gl_xiaoming)
複製代碼
return
關鍵字能夠返回結果,調用函數一方,能夠 使用變量 來 接收 函數的返回結果。注意:
return
表示返回,後續的代碼都不會被執行
def sum_2_num(num1, num2):
"""對兩個數字的求和"""
return num1 + num2
# 調用函數,並使用 result 變量接收計算結果
result = sum_2_num(10, 20)
print("計算結果是 %d" % result)
複製代碼
技巧
Python
中,能夠 將一個元組 使用 賦值語句 同時賦值給 多個變量# Python 專有,利用元組交換兩個變量的值
a, b = b, a
複製代碼
def test1():
print("*" * 50)
print("test 1")
print("*" * 50)
def test2():
print("-" * 50)
print("test 2")
test1()
print("-" * 50)
test2()
複製代碼
提示:工做中針對需求的變化,應該冷靜思考,不要輕易修改以前已經完成的,可以正常執行的函數!
函數調用自身的 編程技巧 稱爲遞歸
特色:一個函數 內部 調用本身
代碼特色:
案例 —— 計算數字累加:
需求:
sum_numbers
num
的整數參數def sum_numbers(num):
if num == 1:
return 1
# 假設 sum_numbers 可以完成 num - 1 的累加
temp = sum_numbers(num - 1)
# 函數內部的核心算法就是 兩個數字的相加
return num + temp
print(sum_numbers(2))
複製代碼
模塊是 Python 程序架構的一個核心概念
模塊 就比如是 工具包,要想使用這個工具包中的工具,就須要 導入 import 這個模塊, 每個以擴展名 py
結尾的 Python
源代碼文件都是一個 模塊,在模塊中定義的 全局變量 、 函數 都是模塊可以提供給外界直接使用的工具。
import
導入這個模塊模塊名.變量
/ 模塊名.函數
的方式,使用這個模塊中定義的變量或者函數模塊可讓 曾經編寫過的代碼 方便的被 複用! 模塊名也是一個標識符,若是在給 Python 文件起名時,以數字開頭 是沒法在
PyCharm
中經過導入這個模塊的。
C
是compiled
編譯過 的意思。
__pycache__
的目錄。hm_10_分隔線模塊.cpython-35.pyc
文件,cpython-35
表示 Python
解釋器的版本。pyc
文件是由 Python 解釋器將 模塊的源碼 轉換爲 字節碼。Python
這樣保存 字節碼 是做爲一種啓動 速度的優化。
Python
在解釋源程序時是分紅兩個步驟的:
Python
重編譯時,它會自動檢查源文件和字節碼文件的時間戳。文件的做用:將數據長期保存下來,在須要的時候使用 文件的存儲方式:在計算機中,文件是以 二進制 的方式保存在磁盤上的 文本文件:可使用 文本編輯軟件 查看,本質上仍是二進制文件 二進制文件:保存的內容 不是給人直接閱讀的,而是 提供給其餘軟件使用的,例如:圖片文件、音頻文件、視頻文件等等,二進制文件不能使用 文本編輯軟件 查看
操做文件的套路: 在 計算機 中要操做文件的套路很是固定,一共包含三個步驟:
操做文件的函數/方法 在 Python
中要操做文件須要記住 1 個函數和 3 個方法
序號 | 函數/方法 | 說明 |
---|---|---|
01 | open | 打開文件,而且返回文件操做對象 |
02 | read | 將文件內容讀取到內存 |
03 | write | 將指定內容寫入文件 |
04 | close | 關閉文件 |
open
函數負責打開文件,而且返回文件對象 read
/write
/close
三個方法都須要經過 文件對象 來調用
讀取文件示例
open
函數的第一個參數是要打開的文件名(文件名區分大小寫) 若是文件 存在,返回 文件操做對象 若是文件 不存在,會 拋出異常
read
方法能夠一次性 讀入 並 返回 文件的 全部內容
close
方法負責 關閉文件 若是 忘記關閉文件,會形成系統資源消耗,並且會影響到後續對文件的訪問
注意:read
方法執行後,會把 文件指針 移動到 文件的末尾
# 1\. 打開 - 文件名須要注意大小寫
file = open("README")
# 2\. 讀取
text = file.read()
print(text)
# 3\. 關閉
file.close()
複製代碼
提示
read
方法後,文件指針 會移動到 讀取內容的末尾
思考:若是執行了一次 read
方法,讀取了全部內容,那麼再次調用 read
方法,還可以得到到內容嗎? 答案:不能!第一次讀取以後,文件指針移動到了文件末尾,再次調用不會讀取到任何的內容。
open
函數默認以 只讀方式 打開文件,而且返回文件對象f = open("文件名", "訪問方式")
複製代碼
訪問方式 | 說明 |
---|---|
r | 以只讀方式打開文件。文件的指針將會放在文件的開頭,這是默認模式。若是文件不存在,拋出異常 |
w | 以只寫方式打開文件。若是文件存在會被覆蓋。若是文件不存在,建立新文件 |
a | 以追加方式打開文件。若是該文件已存在,文件指針將會放在文件的結尾。若是文件不存在,建立新文件進行寫入 |
r+ | 以讀寫方式打開文件。文件的指針將會放在文件的開頭。若是文件不存在,拋出異常 |
w+ | 以讀寫方式打開文件。若是文件存在會被覆蓋。若是文件不存在,建立新文件 |
a+ | 以讀寫方式打開文件。若是該文件已存在,文件指針將會放在文件的結尾。若是文件不存在,建立新文件進行寫入 |
提示:頻繁的移動文件指針,會影響文件的讀寫效率,開發中更多的時候會以 只讀、只寫 的方式來操做文件
寫入文件示例
# 打開文件
f = open("README", "w")
f.write("hello python!\n")
f.write("今每天氣真好")
# 關閉文件
f.close()
複製代碼
readline()
read
方法默認會把文件的 全部內容 一次性讀取到內存readline
方法能夠一次讀取一行內容讀取大文件的正確姿式
# 打開文件
file = open("README")
while True:
# 讀取一行內容
text = file.readline()
# 判斷是否讀到內容
if not text:
break
# 每讀取一行的末尾已經有了一個 `\n`
print(text, end="")
# 關閉文件
file.close()
複製代碼
複製大文件
# 1\. 打開文件
file_read = open("README")
file_write = open("README[復件]", "w")
# 2\. 讀取並寫入文件
while True:
# 每次讀取一行
text = file_read.readline()
# 判斷是否讀取到內容
if not text:
break
file_write.write(text)
# 3\. 關閉文件
file_read.close()
file_write.close()
複製代碼
os
模塊文件管理操做
序號 | 方法名 | 說明 | 示例 |
---|---|---|---|
01 | rename | 重命名文件 | os.rename(源文件名, 目標文件名) |
02 | remove | 刪除文件 | os.remove(文件名) |
目錄管理操做
序號 | 方法名 | 說明 | 示例 |
---|---|---|---|
01 | listdir | 目錄列表 | os.listdir(目錄名) |
02 | mkdir | 建立目錄 | os.mkdir(目錄名) |
03 | rmdir | 刪除目錄 | os.rmdir(目錄名) |
04 | getcwd | 獲取當前目錄 | os.getcwd() |
05 | chdir | 修改工做目錄 | os.chdir(目標目錄) |
06 | path.isdir | 判斷是不是文件 | os.path.isdir(文件路徑) |
提示:文件或者目錄操做都支持 相對路徑 和 絕對路徑
ASCII
編碼,UNICODE
編碼等Python 2.x 默認使用
ASCII
編碼格式 Python 3.x 默認使用UTF-8
編碼格式
ASCII
編碼
256
個 ASCII
字符ASCII
在內存中佔用 1 個字節 的空間
8
個 0/1
的排列組合方式一共有 256
種,也就是 2 ** 8
UTF-8
編碼格式
UTF-8
字符,涵蓋了 地球上幾乎全部地區的文字UTF-8
是 UNICODE
編碼的一種編碼格式Ptyhon 2.x 中如何使用中文?
# *-* coding:utf8 *-*
,解釋器會以 utf-8
編碼來處理 python 文件,這方式是官方推薦使用的!# coding=utf8
。Python 2.x 中如何正確遍歷 unicode 字符串?
UTF-8
的編碼格式,可是在遍歷字符串時,仍然會 以字節爲單位遍歷 字符串u
,告訴解釋器這是一個 unicode
字符串(使用 UTF-8
編碼格式的字符串)# *-* coding:utf8 *-*
# 在字符串前,增長一個 `u` 表示這個字符串是一個 utf8 字符串
hello_str = u"你好世界"
print(hello_str)
for c in hello_str:
print(c)
複製代碼
Python 解釋器
遇到 到一個錯誤,會中止程序的執行,而且提示一些錯誤信息,這就是 異常程序開發時,很難將 全部的特殊狀況 都處理的面面俱到,經過 異常捕獲 能夠針對突發事件作集中的處理,從而保證程序的 穩定性和健壯性
try except else finally
簡單的捕獲異常語法
try(嘗試)
來 捕獲異常try:
嘗試執行的代碼
except:
出現錯誤的處理
複製代碼
try
嘗試,下方編寫要嘗試代碼,不肯定是否可以正常執行的代碼except
若是不是,下方編寫嘗試失敗的代碼簡單異常捕獲1 —— 要求用戶輸入整數
try:
# 提示用戶輸入一個數字
num = int(input("請輸入數字:"))
except:
print("請輸入正確的數字")
複製代碼
錯誤類型捕獲
try:
# 嘗試執行的代碼
pass
except 錯誤類型1:
# 針對錯誤類型1,對應的代碼處理
pass
except (錯誤類型2, 錯誤類型3):
# 針對錯誤類型2 和 3,對應的代碼處理
pass
except Exception as result:
print("未知錯誤 %s" % result)
複製代碼
Python
解釋器 拋出異常 時,最後一行錯誤信息的第一個單詞,就是錯誤類型異常類型捕獲2 —— 要求用戶輸入整數
try:
num = int(input("請輸入整數:"))
result = 8 / num
print(result)
except ValueError:
print("請輸入正確的整數")
except ZeroDivisionError:
print("除 0 錯誤")
複製代碼
捕獲未知錯誤
Python
解釋器 拋出異常而被終止,能夠再增長一個 except
語法以下:
except Exception as result:
print("未知錯誤 %s" % result)
複製代碼
異常捕獲完整語法
try:
# 嘗試執行的代碼
pass
except 錯誤類型1:
# 針對錯誤類型1,對應的代碼處理
pass
except 錯誤類型2:
# 針對錯誤類型2,對應的代碼處理
pass
except (錯誤類型3, 錯誤類型4):
# 針對錯誤類型3 和 4,對應的代碼處理
pass
except Exception as result:
# 打印錯誤信息
print(result)
else:
# 沒有異常纔會執行的代碼
pass
finally:
# 不管是否有異常,都會執行的代碼
print("不管是否有異常,都會執行的代碼")
複製代碼
else
只有在沒有異常時纔會執行的代碼
finally
不管是否有異常,都會執行的代碼
以前一個演練的 完整捕獲異常 的代碼以下:
try:
num = int(input("請輸入整數:"))
result = 8 / num
print(result)
except ValueError:
print("請輸入正確的整數")
except ZeroDivisionError:
print("除 0 錯誤")
except Exception as result:
print("未知錯誤 %s" % result)
else:
print("正常執行")
finally:
print("執行完成,可是不保證正確")
複製代碼
提示:
- 在開發中,能夠在主函數中增長 異常捕獲,而在主函數中調用的其餘函數,只要出現異常,都會傳遞到主函數的異常捕獲中
- 這樣就不須要在代碼中,增長大量的異常捕獲,可以保證代碼的整潔
''' 需求: 1. 定義函數 `demo1()` **提示用戶輸入一個整數而且返回** 2. 定義函數 `demo2()` 調用 `demo1()` 3. 在主程序中調用 `demo2()` '''
def demo1():
return int(input("請輸入一個整數:"))
def demo2():
return demo1()
try:
print(demo2())
except ValueError:
print("請輸入正確的整數")
except Exception as result:
print("未知錯誤 %s" % result)
複製代碼
raise
應用場景
Python
解釋器會 拋出 異常以外示例
拋出異常
Python
中提供了一個 Exception
異常類Exception
的 對象raise
關鍵字 拋出 異常對象''' **需求** * 定義 `input_password` 函數,提示用戶輸入密碼 * 若是用戶輸入長度 < 8,拋出異常 * 若是用戶輸入長度 >=8,返回輸入的密碼 '''
def input_password():
# 1\. 提示用戶輸入密碼
pwd = input("請輸入密碼:")
# 2\. 判斷密碼長度,若是長度 >= 8,返回用戶輸入的密碼
if len(pwd) >= 8:
return pwd
# 3\. 密碼長度不夠,須要拋出異常
# 1> 建立異常對象 - 使用異常的錯誤信息字符串做爲參數
ex = Exception("密碼長度不夠")
# 2> 拋出異常對象
raise ex
try:
user_pwd = input_password()
print(user_pwd)
except Exception as result:
print("發現錯誤:%s" % result)
複製代碼
模塊是 Python 程序架構的一個核心概念
py
結尾的 Python
源代碼文件都是一個 模塊模塊的兩種導入方式
1)import 導入
import 模塊名1, 模塊名2
複製代碼
提示:在導入模塊時,每一個導入應該獨佔一行
import 模塊名1
import 模塊名2
複製代碼
模塊名.
使用 模塊提供的工具 —— 全局變量、函數、類as
指定模塊的別名若是模塊的名字太長,可使用
as
指定模塊的名稱,以方便在代碼中的使用
import 模塊名1 as 模塊別名
複製代碼
注意:模塊別名 應該符合 大駝峯命名法
2)from...import 導入
from ... import
的方式import 模塊名
是 一次性 把模塊中 全部工具所有導入,而且經過 模塊名/別名 訪問# 從 模塊 導入 某一個工具
from 模塊名1 import 工具名
複製代碼
注意
若是 兩個模塊,存在 同名的函數,那麼 後導入模塊的函數,會 覆蓋掉先導入的函數
import
代碼應該統一寫在 代碼的頂部,更容易及時發現衝突as
關鍵字 給其中一個工具起一個別名from...import *
# 從 模塊 導入 全部工具
from 模塊名1 import *
複製代碼
注意
這種方式不推薦使用,由於函數重名並無任何的提示,出現問題很差排查
Python
的解釋器在 導入模塊 時,會:
在開發時,給文件起名,不要和 系統的模塊文件 重名
Python
中每個模塊都有一個內置屬性__file__
能夠 查看模塊 的 完整路徑
原則 —— 每個文件都應該是能夠被導入的
Python
文件 就是一個 模塊實際開發場景
__name__
屬性
__name__
屬性能夠作到,測試模塊的代碼 只在測試狀況下被運行,而在 被導入時不會被執行!__name__
是 Python
的一個內置屬性,記錄着一個 字符串__name__
就是 模塊名__name__
是 __main__
在不少 Python
文件中都會看到如下格式的代碼:
# 導入模塊
# 定義全局變量
# 定義類
# 定義函數
# 在代碼的最下方
def main():
# ...
pass
# 根據 __name__ 判斷是否執行下方代碼
if __name__ == "__main__":
main()
複製代碼
__init__.py
_
好處:使用 import 包名
能夠一次性導入 包 中 全部的模塊
案例
hm_message
的 包send_message
和 receive_message
send_message
文件中定義一個 send
函數receive_message
文件中定義一個 receive
函數hm_message
的包__init__.py
__init__.py
中指定 對外界提供的模塊列表# 從 當前目錄 導入 模塊列表
from . import send_message
from . import receive_message
複製代碼
setup.py
的文件from distutils.core import setup
setup(name="hm_message", # 包名
version="1.0", # 版本
description="itheima's 發送和接收消息模塊", # 描述信息
long_description="完整的發送和接收消息模塊", # 完整描述信息
author="itheima", # 做者
author_email="itheima@itheima.com", # 做者郵箱
url="www.itheima.com", # 主頁
py_modules=["hm_message.send_message",
"hm_message.receive_message"])
複製代碼
有關字典參數的詳細信息,能夠參閱官方網站:docs.python.org/2/distutils…
$ python3 setup.py build
複製代碼
$ python3 setup.py sdist
複製代碼
注意:要製做哪一個版本的模塊,就使用哪一個版本的解釋器執行!
4)安裝模塊
$ tar -zxvf hm_message-1.0.tar.gz
$ sudo python3 setup.py install
複製代碼
5)卸載模塊
直接從安裝目錄下,把安裝模塊的 目錄 刪除就能夠
$ cd /usr/local/lib/python3.5/dist-packages/
$ sudo rm -r hm_message*
複製代碼
pip
安裝第三方模塊
Python
包 / 模塊
pygame
就是一套很是成熟的 遊戲開發模塊pip
是一個現代的,通用的 Python
包管理工具Python
包的查找、下載、安裝、卸載等功能安裝和卸載命令以下:
# 將模塊安裝到 Python 2.x 環境
$ sudo pip install pygame
$ sudo pip uninstall pygame
# 將模塊安裝到 Python 3.x 環境
$ sudo pip3 install pygame
$ sudo pip3 uninstall pygame
複製代碼
面向對象編程 —— Object Oriented Programming
簡寫 OOP
面向對象 —— 誰來作?
相比較函數,面向對象 是更大的封裝,根據職責在 一個對象中封裝多個方法
在完成某一個需求前,首先肯定 職責 —— 要作的事情(方法) 根據 職責 肯定不一樣的 對象,在 對象 內部封裝不一樣的 方法(多個) 最後完成的代碼,就是順序地讓 不一樣的對象 調用 不一樣的方法 特色: 注重 對象和職責,不一樣的對象承擔不一樣的職責 更加適合應對複雜的需求變化,是專門應對複雜項目開發,提供的固定套路 須要在面向過程基礎上,再學習一些面向對象的語法
在 Python 中 對象幾乎是無所不在的,咱們以前學習的 變量、數據、函數 都是對象。 在 Python 中可使用如下兩個方法驗證:
標識符 / 數據
後輸入一個點 .
,而後按下 TAB
鍵,iPython 會提示該對象可以調用的方法列表。dir
傳入 標識符 / 數據
,能夠查看對象內的 全部屬性及方法。 提示__方法名__
格式的方法是 Python 提供的 內置方法 / 屬性
。序號 | 方法名 | 類型 | 做用 |
---|---|---|---|
01 | __new__ |
方法 | 建立對象時,會被 自動 調用 |
02 | __init__ |
方法 | 對象被初始化時,會被 自動 調用 |
03 | __del__ |
方法 | 對象被從內存中銷燬前,會被 自動 調用 |
04 | __str__ |
方法 | 返回對象的描述信息,print 函數輸出使用 |
提示 利用好 dir()
函數,在學習時不少內容就不須要死記硬背了。
面向對象是更大的封裝,在 一個類中封裝多個方法,這樣經過這個類建立出來的對象,就能夠直接調用這些方法了!
定義一個只包含方法的類:
class 類名:
def 方法1(self, 參數列表):
pass
def 方法2(self, 參數列表):
pass
複製代碼
方法 的定義格式和以前學習過的函數幾乎同樣,區別在於第一個參數必須是 self
。 注意:類名 的 命名規則 要符合 大駝峯命名法。 當一個類定義完成以後,要使用這個類來建立對象,語法格式以下:
對象變量 = 類名()
複製代碼
在面向對象開發中,引用的概念是一樣適用的!
使用 print
輸出 對象變量,默認狀況下,是可以輸出這個變量 引用的對象 是 由哪個類建立的對象,以及 在內存中的地址(十六進制表示)。
提示:在計算機中,一般使用 十六進制 表示 內存地址。
若是在開發中,但願使用 print
輸出 對象變量 時,可以打印 自定義的內容,就能夠利用 __str__
這個內置方法了:
class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s 來了" % self.name)
def __del__(self):
print("%s 去了" % self.name)
def __str__(self):
return "我是小貓:%s" % self.name
tom = Cat("Tom")
print(tom)
複製代碼
注意:
__str__
方法必須返回一個字符串。
在 Python 中,要 給對象設置屬性,很是的容易,只須要在 類的外部的代碼 中直接經過 對象.
設置一個屬性便可,可是不推薦使用:
class Cat:
"""這是一個貓類"""
def eat(self):
print("小貓愛吃魚")
def drink(self):
print("小貓在喝水")
tom = Cat()
# 給對象設置屬性
tom.name = "Tom"
複製代碼
由於:對象屬性的封裝應該封裝在類的內部
由哪個對象調用的方法,方法內的
self
就是哪個對象的引用
self
就表示當前調用方法的對象本身,在方法內部: 能夠經過 self.
訪問對象的屬性,也能夠經過 self.
調用對象的其餘方法。變量名.
訪問對象的 屬性和方法 在 類封裝的方法中,經過 self.
訪問對象的 屬性和方法__init__
類名()
建立對象時,會 自動 執行如下操做: 爲對象在內存中分配空間 —— 建立對象 爲對象的屬性設置初始值 —— 初始化方法(__init__
)
__init__
方法是 專門 用來定義一個類具備哪些屬性的方法!
在 __init__
方法內部使用 self.屬性名 = 屬性的初始值
就能夠定義屬性,定義屬性以後,再使用 類建立的對象,都會擁有該屬性。
在開發中,若是但願在 建立對象的同時,就設置對象的屬性,能夠對 __init__
方法進行 改造:
__init__
方法的參數self.屬性 = 形參
接收外部傳遞的參數類名(屬性1, 屬性2...)
調用class Cat:
def __init__(self, name):
print("初始化方法 %s" % name)
self.name = name
...
tom = Cat("Tom")
...
lazy_cat = Cat("大懶貓")
...
複製代碼
應用場景
定義方式
僞私有屬性和私有方法 Python 中,並無 真正意義 的 私有 在給 屬性、方法 命名時,實際是對名稱作了一些特殊處理,使得外界沒法訪問到 處理方式:在 名稱 前面加上_類名
=> _類名__名稱
# 私有屬性,外部不能直接訪問到
print(xiaofang._Women__age)
# 私有方法,外部不能直接調用
xiaofang._Women__secret()
複製代碼
提示:在平常開發中,不要使用這種方式,訪問對象的 私有屬性 或 私有方法。
面向對象三大特性:
繼承的概念:子類 擁有 父類 以及 父類的父類 中封裝的全部 屬性 和 方法。
class 類名(父類名):
pass
複製代碼
當 父類 的方法實現不能知足子類需求時,能夠對方法進行重寫(override) 重寫 父類方法有兩種狀況:
super().父類方法
來調用父類方法的執行代碼;其餘的位置針對子類的需求,編寫 子類特有的代碼實現。super
是一個 特殊的類super()
就是使用 super 類
建立出來的對象調用父類方法的另一種方式:在 Python 2.x 時,若是須要調用父類的方法,還可使用如下方式:
父類名.方法(self)
。目前在 Python 3.x 還支持這種方式,但不推薦使用,由於一旦 父類發生變化,方法調用位置的 類名 一樣須要修改。
子類對象 不能 在本身的方法內部,直接 訪問 父類的 私有屬性 或 私有方法 子類對象 能夠經過 父類 的 公有方法 間接 訪問到 私有屬性 或 私有方法
- 私有屬性、方法 是對象的隱私,不對外公開,外界 以及 子類 都不能直接訪問
- 私有屬性、方法 一般用於作一些內部的事情
子類 能夠擁有 多個父類,而且具備 全部父類 的 屬性 和 方法,例如:孩子 會繼承本身 父親 和 母親 的 特性。
class 子類名(父類名1, 父類名2...):
pass
複製代碼
__mro__
能夠查看 方法 搜索順序
MRO 是 method resolution order —— 方法搜索順序,主要用於 在多繼承時判斷 方法、屬性 的調用 路徑
object
爲基類的類,推薦使用object
爲基類的類,不推薦使用在 Python 3.x 中定義類時,若是沒有指定父類,會 默認使用 object做爲該類的 基類 —— Python 3.x 中定義的類都是 新式類,在 Python 2.x 中定義類時,若是沒有指定父類,則不會以 object 做爲 基類。
class 類名(object):
pass
複製代碼
object
是 Python 爲全部對象提供的 基類,提供有一些內置的屬性和方法,可使用dir(object)
函數查看。
面向對象三大特性:
多態 更容易編寫出出通用的代碼,作出通用的編程,以適應需求的不斷變化!
案例: 在 Dog 類中封裝方法 game:普通狗只是簡單的玩耍 定義 XiaoTianDog 繼承自 Dog,而且重寫 game 方法:哮天犬須要在天上玩耍 定義 Person 類,而且封裝一個 和狗玩 的方法:在方法內部,直接讓 狗對象 調用 game 方法
Person 類中只須要讓 狗對象 調用 game 方法,而不關心具體是 什麼狗。一般會把: 建立出來的 對象 叫作 類的實例 建立對象的 動做 叫作 實例化 對象的屬性 叫作 實例屬性 對象調用的方法 叫作 實例方法 每個對象 都有本身獨立的內存空間,保存各自不一樣的屬性 多個對象的方法,在內存中只有一份,在調用方法時,須要把對象的引用傳遞到方法內部
在 Python 中,類是一個特殊的對象。
Python 中 一切皆對象:
- class AAA: 定義的類屬於 類對象
- obj1 = AAA() 屬於 實例對象
在程序運行時,類一樣會被加載到內存 在程序運行時,類對象在內存中只有一份,使用 一個類能夠建立出不少個對象實例 除了封裝實例的屬性和方法外,類對象還能夠擁有本身的屬性和方法——類屬性、類方法,經過 類名.
的方式能夠 訪問類的屬性 或者 調用類的方法
類屬性 就是 類對象中定義的屬性 一般用來記錄與這個類相關的特徵 類屬性不會用於記錄具體對象的特徵 示例: 定義一個 工具類,每件工具都有本身的 name
: 需求 —— 知道使用這個類,建立了多少個工具對象?
class Tool(object):
# 使用賦值語句,定義類屬性,記錄建立工具對象的總數
count = 0
def __init__(self, name):
self.name = name
# 針對類屬性作一個計數+1
Tool.count += 1
# 建立工具對象
tool1 = Tool("斧頭")
tool2 = Tool("榔頭")
tool3 = Tool("鐵鍬")
# 知道使用 Tool 類到底建立了多少個對象?
print("如今建立了 %d 個工具" % Tool.count)
複製代碼
在 Python 中 屬性的獲取 存在一個 向上查找機制
所以,要訪問類屬性有兩種方式:
類名.類屬性
對象.類屬性
(不推薦,由於若是使用 對象.類屬性 = 值
賦值語句,只會給對象添加一個屬性,而不會影響到類屬性的值)class
關鍵字下方能夠定義 類屬性語法以下
@classmethod
def 類方法名(cls):
pass
複製代碼
@classmethod
來標識,告訴解釋器這是一個類方法cls
cls
就是 哪個類的引用self
相似cls
cls
參數cls.
訪問類的屬性cls.
調用其餘的類方法示例
name
show_tool_count
的類方法,輸出使用當前這個類,建立的對象個數@classmethod
def show_tool_count(cls):
"""顯示工具對象的總數"""
print("工具對象的總數 %d" % cls.count)
複製代碼
語法以下
@staticmethod
def 靜態方法名():
pass
複製代碼
@staticmethod
來標識,告訴解釋器這是一個靜態方法示例:
show_help
顯示遊戲幫助信息show_top_score
顯示歷史最高分start_game
開始當前玩家的遊戲class Game(object):
# 遊戲最高分,類屬性
top_score = 0
@staticmethod
def show_help():
print("幫助信息:讓殭屍走進房間")
@classmethod
def show_top_score(cls):
print("遊戲最高分是 %d" % cls.top_score)
def __init__(self, player_name):
self.player_name = player_name
def start_game(self):
print("[%s] 開始遊戲..." % self.player_name)
# 使用類名.修改歷史最高分
Game.top_score = 999
# 1. 查看遊戲幫助
Game.show_help()
# 2. 查看遊戲最高分
Game.show_top_score()
# 3. 建立遊戲對象,開始遊戲
game = Game("小明")
game.start_game()
# 4. 遊戲結束,查看遊戲最高分
Game.show_top_score()
複製代碼
探索:
設計模式
單例設計模式
類名()
返回的對象,內存地址是相同的單例設計模式的應用場景
__new__
Python
的解釋器 首先 會 調用 __new__
方法爲對象 分配空間__new__
是一個 由 object
基類提供的 內置的靜態方法,主要做用有兩個:
Python
的解釋器得到對象的 引用 後,將引用做爲 第一個參數,傳遞給 __init__
方法重寫
__new__
方法 的代碼很是固定!
__new__
方法 必定要 return super().__new__(cls)
,不然 Python 的解釋器 得不到 分配了空間的 對象引用,就不會調用對象的初始化方法__new__
是一個靜態方法,在調用時須要 主動傳遞 cls
參數class MusicPlayer(object):
def __new__(cls, *args, **kwargs):
# 若是不返回任何結果,就不會調用對象的初始化方法
return super().__new__(cls)
def __init__(self):
print("初始化音樂播放對象")
player = MusicPlayer()
print(player)
複製代碼
None
,用於記錄 單例對象的引用__new__
方法is None
,調用父類方法分配空間,並在類屬性中記錄結果class MusicPlayer(object):
# 定義類屬性記錄單例對象引用
instance = None
def __new__(cls, *args, **kwargs):
# 1\. 判斷類屬性是否已經被賦值
if cls.instance is None:
cls.instance = super().__new__(cls)
# 2\. 返回類屬性的單例引用
return cls.instance
複製代碼
類名()
建立對象時,Python
的解釋器都會自動調用兩個方法:
__new__
分配空間__init__
對象初始化__new__
方法改造以後,每次都會獲得 第一次被建立對象的引用需求
解決辦法
init_flag
標記是否 執行過初始化動做,初始值爲 False
__init__
方法中,判斷 init_flag
,若是爲 False
就執行初始化動做init_flag
設置爲 True
__init__
方法時,初始化動做就不會被再次執行 了class MusicPlayer(object):
# 記錄第一個被建立對象的引用
instance = None
# 記錄是否執行過初始化動做
init_flag = False
def __new__(cls, *args, **kwargs):
# 1\. 判斷類屬性是不是空對象
if cls.instance is None:
# 2\. 調用父類的方法,爲第一個對象分配空間
cls.instance = super().__new__(cls)
# 3\. 返回類屬性保存的對象引用
return cls.instance
def __init__(self):
if not MusicPlayer.init_flag:
print("初始化音樂播放器")
MusicPlayer.init_flag = True
# 建立多個對象
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2)
複製代碼
一、Python 可以自動的將一對括號內部的代碼鏈接在一塊兒:
return ("戶型:%s\n總面積:%.2f[剩餘:%.2f]\n傢俱:%s"
% (self.house_type, self.area,
self.free_area, self.item_list))
複製代碼
二、一個對象的 屬性 能夠是 另一個類建立的對象。 三、在__init__
方法中定義類的屬性時,若是 不知道設置什麼初始值,能夠設置爲 None
):None
關鍵字 表示 什麼都沒有,表示一個 空對象,沒有方法和屬性,是一個特殊的常量。能夠將 None 賦值給任何一個變量。
在 Python 中針對
None
比較時,建議使用is
判斷
四、eval() 函數十分強大 —— 將字符串 當成 有效的表達式 來求值 並 返回計算結果
# 基本的數學計算
In [1]: eval("1 + 1")
Out[1]: 2
# 字符串重複
In [2]: eval("'*' * 10")
Out[2]: '**********'
# 將字符串轉換成列表
In [3]: type(eval("[1, 2, 3, 4, 5]"))
Out[3]: list
# 將字符串轉換成字典
In [4]: type(eval("{'name': 'xiaoming', 'age': 18}"))
Out[4]: dict
複製代碼
在開發時千萬不要使用 eval 直接轉換 input 的結果,舉個例子:
__import__('os').system('ls')
# 等價代碼
import os
os.system("終端命令")
複製代碼
參考教程: 1.【易百python教程】https://www.yiibai.com/python