python3 學習筆記

Python3 Study Notes

本人不多寫 python 代碼, 通常都是用 go 的, 去年時用 python 寫過一些收集系統信息的工具, 當時是邊看手冊邊寫的. 現在又要用 python 來寫一個生成 xlsx 的工具, 就又須要查看手冊了, 至於爲何不用 go 寫? 那是由於 go 的庫不兼容永中. 在這裏不得不說, 雖然 go 很火, 可是一些庫仍是不如 python 多, 不如 python 兼容性好.python

爲了不之後再出這種事情, 此次就好好的瞭解下 python, 將它的用法按照本身對語言的理解分塊記錄下來. 要使用某種語言, 我的認爲須要瞭解這些方面:linux

  • 編碼風格
  • 變量的類型, 聲明及使用方式
  • 輸入/輸出
  • 控制語句的寫法
  • 錯誤處理的用法
  • 函數的用法, 還有語言支持的一些特性, python 中就有裝飾器, lambda 語句等
  • 對於面嚮對象語言還須要瞭解類的聲明, 繼承, 多態等的用法

還有一些就是此語言的一些特性, python 就還須要瞭解如下特性:express

  • 模塊的使用

下文就將按照這些內容來一一記錄.編程


編碼風格

  • 變量名, 方法名和模塊名建議小寫, 單詞以 _ 分割, 類名建議駝峯命名風格, 首字母大寫, 私有類可用一個 _ 開頭.
  • 每行結尾儘可能不要添加 ;, 多行代碼也不要寫在一行
  • python 是以縮進來控制代碼段的, 因此縮減建議使用 4 個空格
  • 編碼儘可能使用 utf-8, python 默認使用 ASCII, 因此要在文件的開頭添加 # -*- coding: UTF-8 -*- 或者 #coding=utf-8 來指定
  • python 有獨一無二的註釋方式: 文檔字符串, 因此註釋儘可能用文檔字符串("""xxxx""")
  • 若是一個類不從其餘類繼承, 就顯示的從 object 類繼承
  • 使用 with 語句來管理文件, 如 openclose
  • 添加 TODO 時, 儘可能在其後緊跟 (), 在裏面寫明做者名或 email 等其餘標識信息, 而後緊跟一個 : 後面接着寫要作的事情
  • 每一個導入模塊都佔一行, 不要一行導入多個模塊
  • 儘可能定義一個 main 函數, 將主程序放入其中, 並在 "if <span class="underline"><span class="underline">name</span></span> = '__main__':" 成立時執行 =main, 這樣被看成模塊導入時就不會執行主程序

變量

Python 是動態語言, 變量的類型不固定, 根據值的類型而決定, 因此不用顯示的聲明變量, 用的時候直接賦值便可,以下:數組

a = 1; // 此時是整型
print(a);
a = 'hello'; // 此時又爲字符串類型

一般變量名所有大寫的爲 常量, 空值None 表示.網絡

_xxx__xxx 命名的函數或變量是私有變量, 不能被其餘模塊直接引用app

基礎類型

這裏將整型, 浮點型, 布爾和字符串看做是基本類型, 整型和浮點型的使用就再也不介紹了, 布爾的值只能爲 True/False, 而字符串的常見操做以下:編程語言

  • 使用 """''' 能夠嵌入長字符串
  • 字符串能夠經過下標來索引, len 函數獲取長度
  • 使用 + 進行拼接操做
  • 字符串對象還內置了不少方法提供了一些常見功能, 具體請查閱手冊

另外它們之間的相互轉換是經過 int(arg), float(arg), str(arg) 這些內置的方法來處理的.函數

列表

列表中能夠包含不一樣類型的數據, 如:工具

list = ["eggs", 1, 67.12];

經過 list(seq) 能夠將一個序列轉換爲列表.

array 模塊提供了固定類型的數據, 能夠指定要轉換的類型, 具體請查閱手冊.

列表經過下標索引, len 函數獲取大小.

列表對象經常使用的方法以下:

  • append(item): 附加元素
  • insert(idx, item): 插入元素
  • pop(idx): 刪除指定位置的元素, 參數爲空則刪除最後一個元素

列表遍歷:

for <variable> in <array>:
    // do

// 帶下標
for idx, name in enumerate(<array>):
    // do

// 列表中多個元素
for x, y in [(1, 1), (2, 4), (3, 9)]:
    // do

// 用 zip 同時遍歷多個數組
a = [1, 2];
b = [5, 6];
for av, bv in zip(a, b):
    // do av=1, bv=5

// 生成
[x * x for x in range(1, 11) if x % 2 == 0]

元組

元組(tuple) 是一個不可修改的列表, 元組中每一個元素的指向是不可更改的, 但指向裏的內容是能夠更改的, 如元組中包含一個數組:

t = ('1', 1, ["A", "B"]);
t[2][0] = "X";
t[2][1] = "Y";

字典

語法:

dict = {'<key>':<value>}

經常使用的對象方法:

  • get(key, value): 獲取指定 key 的值, 若是不存在則返回 value, 若是 value 未指定則返回 None
  • pop(key): 刪除指定的 key

使用字典須要注意如下幾點:

  • 字典中的 key 不能重複
  • 字典中的 key 不可變, 因此只能用數字, 字符串和元組
  • 字典的值則沒有限制, 能夠是任意對象

集合

集合與字典相似, 是一組 key 的集合, 但不存儲 value, 沒有重複的 key.

要建立一個集合, 須要傳入一個數組, 重複的元素會被自動過濾.

遍歷:

for <key> in <dict>:
    // do

// 帶下標
for idx, name in dict.items():
    // do
s = set([1, 2, 3 ,3]); // s: {1,2,3}

經常使用的對象方法:

  • add(key): 添加 key
  • remove(key): 刪除 key

global 關鍵字

global 關鍵字用於聲明變量的做用域, 用法以下:

# 全局變量
a = 1

def test():
    # 若下面這行註釋掉, 則下面的 a 是局部變量, 'Global' 處的輸出仍是全局變量 1
    # 若下面這行取消註釋, 則下面的 a 是全局變量, 'Gloabl' 出的輸出是 5
    # global a
    a = 5
    print("In test:", a)

# Global
print("Global:", a)

輸出, global a 註釋掉時:

In test: 5
Global: 1

輸出, global a 取消註釋時:

In test: 5
Global: 5

更多

上面的只是基礎,想要更好的使用變量,還須要瞭解如下內容:

  • 類型對象的方法

    python 中每種類型都是對象, 都提供了一些內置方法, 如字符串類型的 replace()

  • 變量的內存分配

    變量只是值的引用, 具體的內存分配是在值的這一邊, 有些類型的值是不可變的, 這些是須要深刻了解的

  • 結構體

    python 中沒有結構體, 可使用下列方式實現:

    • 使用 struct 模塊來實現, 須要瞭解與 c 中類型的格式對照, 建立時須要指定結構體的成員類型
    • 使用類來實現, 在類的構造函數 __init__ 中定義結構體成員

輸入/輸出

輸入

使用 raw_input(prompt) 能夠接受控制檯的輸入

輸出

使用 print() 能夠打印內容到控制檯, 格式化輸出:

n = 1;
s = "Joy";
print("The %d student's name is %s" % (n, s));

也可使用 format 來格式化, 它會用傳入的參數依次替換字符串內的佔位符 {0}、{1}…… :

// {3:.1f} 表示保留一位小數
s = "The {0} student's name is {1}, score: {3:.1f}".format(1, "Joy", 87.75);
print(s);

控制語句

控制語句中可使用 break, continue, pass 關鍵字, breakcontinue 的做用與其餘語言中的同樣, pass 則是一個空語句, 不作任何事情, 通常是爲了保持結構的完整性, 常被用來佔位, 代表以後會實現.

注意: python 中沒有 gotoswitch.

IF

語法:

if <condition>:
elif <condition>:
else:

FOR

for <variable> in <array>:
    // do
else:

else 可選

WHILE

while <condition>:
    // do
else:

else 可選


錯誤處理

語法:

try:
    // do
except <error type> as e:
   // do
except <error type> as e:
else:
   // no error
finally:
   // do

若是 finally 存在, 則不管有沒有異常都會執行, else 則在 except 都沒進入時才執行.


函數

語法:

def func(arg1, arg2=value, arg3=value):
    // do
    return ret1, ret2

# 不定長參數
def func(arg1, *vartuple):
   "打印全部參數"
   print(arg1)
   for var in vartuple:
       print(var)
   return

定義函數時能夠給參數指定默認值, 這樣在調用時就能夠不傳入這些參數, 沒有默認值的參數是必需要傳入的.

定義默認參數要牢記一點:默認參數必須指向不變對象(數, 字符串, 元組)!

參數前加了 * 的變量會存放全部未命名的變量.

__name__ 是函數對象的一個屬性, 能夠拿到此函數的名稱

Lambda

使用關鍵字 lambda, 就能夠建立短小的匿名函式, 如:

# 語法
lambda [arg1 [,arg2,.....argn]]:expression

sum = lambda arg1, arg2: arg1 + arg2
print(sum(10, 10) # 20
print(sum(10, 20) # 30

特色:

  • lambda 只是一個表達式, 函數體比 def 簡單的多, 近能封裝有限的邏輯進去
  • lambda 函數擁有本身的命名空間, 而且不能訪問自有參數以外或全局命名的參數
  • lambda 函數雖然間短, 但不等同於 內聯函數

裝飾器

當須要加強某個函數的功能時, 但有不但願修改函數, 此時可使用裝飾器. 如添加日誌功能:

def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

@log
def test():
    print("Test")

經過 @ 語法就給函數 test 添加了日誌功能


模塊

模塊就是一個 python 文件, 使用 import 導入模塊, 調用模塊中的方法時就必須以 <module>.<func> 來調用.

from <module> import <func1>,<func2>... 語句是從模塊中導入指定的函數, from <module> import * 則將模塊中的全部方法都導入

導入一個模塊時的路徑搜索順序以下:

  1. 先從當前目錄查找是否有此模塊
  2. 若是當前目錄沒有, 就從 PYTHONPATH 定義的目錄下查找
  3. 若是都找不到, 就查看默認路徑, linux 下通常是 /usr/lib/python

搜索路徑定義在 sys.path 中, 能夠用 append 函數來添加指定目錄, 如項目中模塊再也不同一個目錄就能夠添加 path 來導入

python 中的包就是一個分層次的目錄, 定義了一個由模塊及子包組成的環境.

包簡單來講就是一個目錄, 目錄中必須包含一個 __init__.py, 該文件能夠爲空, 目的使用來標識這個目錄是一個包, 一個簡單的例子以下:

如存在目錄 package_test , 此目錄下有 __init__.py, foo1.py, foo2.py 等文件

foo1.py 文件:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def foo1():
    print("Foo1 test")

foo2.py 文件:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def foo2():
    print("Foo2 test")

調用:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from package_test.foo1 import foo1
from package_test.foo2 import foo2

if __name__ == "__main__":
    foo1()
    foo2()

python 是一門面向對象語言, 因此建立類和對象是很容易的, 先簡單介紹下面向對象的一些基本特徵:

  • 類: 用來描述具備相同屬性和方法的對象的集合, 定義了每一個對象共有的屬性和方法, 對象是類的實例
  • 數據成員: 類中的變量, 用於處理類及對象的相關的數據
  • 私有成員: 只能在類的內部方法中訪問的成員
  • 受保護成員: 只能由本類或子類訪問的成員
  • 公有成員: 全局的, 類內部, 外部和子類都能訪問的成員
  • 方法: 類中定義的函數
  • 方法重寫: 若是從父類繼承的方法不知足需求, 能夠對其從新實現, 這個過程就叫重寫
  • 操做符重載: 自定義某些操做符的功能, 如 + 操做符, 指明2個對象的數據如何相加
  • 繼承: 從一個父類派生出一個子類
  • 多態: 若是多個對象都繼承子一個父類, 經過傳入一個父類變量來調用某個方法時, 若是此時傳入的是子類的對象, 則會調用這個子類中實現的方法(方法已被重寫)

類的建立

python 中類建立的語法以下:

# 建立一個類
class Human:
    # 類變量
    var1 = 0 # 公有成員
    _var2 = 0 # 受保護成員
    __var3 = 0 # 私有成員

    # 構造函數, 裏面能夠定義實例變量, 這些變量只有在這個函數調用後才能使用, 子類若是重寫了構造函數, 則不能使用這些變量
    def __init__(self, arg1, arg2...):
        self.arg1 = arg1
        self._arg2 = arg2
        self.__arg3 = arg3

    # 類方法
    def foo(self):
        print("Var1:", var1)
        print("Arg1:", self.arg1)

"""
動態類型的語言在建立實例後, 能夠給實例綁定任何的屬性和方法, 但這些綁定只對當前實例有效
若是要對因此實例生效, 能夠在建立實例前給動態的給類綁定
"""

# 動態的給類綁定屬性和方法, 這些屬性和方法全部實例均可用
Human.school = ''
# 實例化
h = Human(arg1, arg2...)
print(h.school)
# 方法調用
h.foo()
# 動態的給實例綁定屬性和方法, 這些屬性和方法只能該實例可用
h.parent = 'Big Joy'
# 類的銷燬
del h

類的實例化是經過調用構造函數完成的, __init__ 函數中定義了實例化時須要的參數.

類中以一個 _ 開頭命令的變量或方法叫作受保護成員, 以二個 _ 開頭命名的叫作私有成員, 以 __ 開頭並以 __ 結尾的爲系統定義的, 通常是內置的成員.

使用 del 則可銷燬一個類實例.

類內置瞭如下屬性:

  • __dict__: 類的數據屬性組成的字典
  • __doc__: 類的文檔
  • __name__: 類名
  • __module__: 類定義所在的模塊名
  • __bases__: 類繼承的全部父類的元組

類的繼承

語法以下:

class SubName(Parent1, Parent2...):
    pass

一個子類能夠繼承多個父類, 使用 isintance(obj, type) 能夠判斷一個對象的類型, 使用 issubclass(sub, parent) 能夠判斷是否爲另外一個類的子類.

方法重寫

若是父類的方法不能知足子類的需求, 子類就可重寫此方法, 在使用子類對象調用此方法時會調用重寫後的方法.

運算符重載 也是方法的重寫, 只不過是對一些內置方法進行重寫.

下面列出一些基本的內置方法:

  • __init__(self, [, args…]): 構造函數, 用戶實例化對象
  • __del__(self): 析構函數, 用於刪除對象
  • __repr__(self): 轉化爲供解釋器讀取的形式
  • __str__(self): 用於將值轉化爲適於人閱讀的形式
  • __cmp__(self, obj): 對象比較
  • __add__(self, obj): '+' 對象相加
  • __sub__(self, obj): '-' 對象相減
  • __eq__(self, obj): '==' 對象是否相等
  • __gt__(self, obj): '>' 對象是否小於
  • __lt__(self, obj): '<' 對象是否小於
  • __iadd__(self, obj): '+=' 對象相加

更多的內置方法請查閱手冊


以上就介紹完了 python 的基礎知識, 按照上面的內容就可以寫出 python 程序了, 固然前提是你不是一個小白, 至少熟悉一門編程語言.

python 還有不少高級知識則須要你自行使用學習了, 如文件操做, 進程和線程, 網絡編程, 圖形編程等等. 本文的目的只是讓你明白 python 程序應該怎麼寫, 怎麼把你用其餘語言寫的程序轉換成 python 語言的, 更多高級的特性只能靠你本身學習嘗試.

相關文章
相關標籤/搜索