我們在上一篇文章中已經學會了如何簡單的運行python命令和腳本,但是,距離真正的寫腳本還有一段距離。
為了防止我們寫出來的腳本運行時報各種語法格式錯誤,我們需要在本章先學習下python的基本語法和腳本格式。
腳本聲明由于Python源代碼也是一個文本文件,所以,當你的源代碼中包含中文的時候,在保存源代碼時,就需要務必指定保存為UTF-8編碼。當Python解釋器讀取源代碼時,為了讓它按UTF-8編碼讀取,我們通常在文件開頭寫上這兩行:
# !/usr/bin/env python # -*- coding:utf-8 -*- 或者 #coding:utf-8
第一行注釋是為了告訴Linux/OS X系統,這是一個Python可執行程序,根據usr/bin/env路徑去找python的運行程序來運行,Windows系統會忽略這個注釋;
第二行注釋是為了告訴Python解釋器,按照UTF-8編碼讀取源代碼,否則,你在源代碼中寫的中文輸出可能會有亂碼。
如果你使用Notepad++進行編輯,除了要加上# -- coding: utf-8 --外,中文字符串必須是Unicode字符串。
模塊(類庫)的引入引入語句一般放在聲明語句後面。
Python在語義中存在着包、模塊、類(當然還有函數)這幾個概念。
在編寫Python代碼時,我們需要管理代碼的文件目錄結構。
這時候會遇到這樣一種情況:
1.由于Python一個文件算一個模塊,一個帶init.py的目錄算一個包。
2.而為了控制代碼文件不要過大,我們需要的是一個類(幾個類或加些許函數)分配一個文件。
Python擁有一個強大的标準庫。
Python語言的核心隻包含數字、字符串、列表、字典、文件等常見類型和函數,而由Python标準庫提供了系統管理、網絡通信、文本處理、數據庫接口、圖形系統、XML處理等額外的功能。Python标準庫命名接口清晰、文檔良好,很容易學習和使用。
如引用,需import,如引入算數模塊,系統模塊
引入mysql數據庫驅動
import math,os,sys import MySQLdb
Python社區提供了大量的第三方模塊,使用方式與标準庫類似。它們的功能無所不包,覆蓋科學計算、Web開發、數據庫接口、圖形系統多個領域,并且大多成熟而穩定。第三方模塊可以使用Python或者C語言編寫。SWIG,SIP常用于将C語言編寫的程序庫轉化為Python模塊。Boost C++ Libraries包含了一組庫,Boost.Python,使得以 Python 或 C++ 編寫的程序能互相調用。借助于擁有基于标準庫的大量工具、能夠使用低級語言如C和可以作為其他庫接口的C++,Python已成為一種強大的應用于其他語言與工具之間的膠水語言。
引用自己寫的模塊則需要注意路徑問題,現在有相對引用和絕對引用的說法,更多詳情可查看。
一般來說自己需要引用所有的py文件放到調用它們的py文件同一目錄下使用import即可。
例如我們有main.py文件和hapdbtools.py文件,放在同一目錄如下:
hapdbtools.py文件聲明了一個類DBtool内容如下:
#coding:utf-8 __author__ = 'zzq' import MySQLdb import sys class DBtool(): def __init__(self): ''' 獲取數據庫連接 __enter__函數配合with 使用 自動調用 enter 和 exit :return: ''' try: self.__db = MySQLdb.connect(host='192.168.1.80', port=3306, db='test', user='zzq', passwd='123456', charset='utf8') self.__cursor = self.__db.cursor() except MySQLdb.Error, e: self.error_code = e.args[0] error_msg = 'MySQL error! ', e.args[0], e.args[1] print error_msg def __enter__(self): ''' 獲取數據庫連接 __enter__函數配合with 使用 自動調用 enter 和 exit :return: ''' self.__db = MySQLdb.connect(host='192.168.1.80', port=3306, db='test', user='zzq', passwd='123456', charset='utf8') self.__cursor = self.__db.cursor() return self def __exit__(self, type, value, traceback): self.__db.close() def query_data_by_barcode(self,barcode): SQL_select_data="select data from mytable where barcode=%s" self.__cursor.execute(SQL_select_data,barcode) result=self.__cursor.fetchall() #result=self.__cursor.fetchone() if result: return result else: return "none"
則main文件中引用時使用語句:
from hapdbtools import DBtool
調用方法時使用語句:
dbtools = DBtool() result = dbtools.query_data_by_barcode(barcode) print(result)
查看哪些腳本調用了hapdbtools腳本使用命令
grep hapdbtools *注釋
# 注釋以 # 字符起始,直至實際的行尾;代碼中注釋不會被Python解釋;文本字符串中的#僅表示# # this is the first comment SPAM = 1 # and this is the second comment STRING = "# This is not a comment" # and this is the third comment ''' 前後三個單引号可進行多行注釋 通常是對函數、對象的說明 注釋代碼仍以 # 為主 '''賦值
# " = " 用于變量賦值;變量直接賦值,無須定義變量類型; 無須定義變量的數據類型 a = 20 #變量在使用前必須賦值,否則會出錯 x = y = z = 1 # 可将同一個值賦給多個變量
在Python中,變量名沒有類型,但對象有;變量名隻是對對象的引用(内部實現為指針)
變量命名規則及慣例
語法: (下劃線或字母)+(任意數目的字母、數字或下劃線)
變量名必須以下劃線或字母開頭,而後面接任意數目的字母、數字或下劃線。
區分大小寫: SPAM和spam不同
禁止使用保留字
命名慣例:
以單一下劃線開頭的變量名(_X)不會被 from module import *語句導入 前後有下劃線的變量名(_X_)是系統定義的變量名,對解釋器有特殊意義 以雙下劃線開頭,但結尾沒有雙下劃線的變量名(__X)是類的本地(“壓縮”)變量 通過交互模式運行時,隻有單個下劃線的變量名(_)會保存最後表達式的結果簡單的輸入、輸出
# 簡單的輸入輸出 raw_input("Please input: ") # Python2.x raw_input() input("Please input: ") # Python3.x input() print "hello world" # Python2.x 可以不用加() print("hello world") # Python3.x 必須要加(),不然會報錯! Python3.x print() 會是空行,而Python2.x print() 則會顯示(),須注意! print("This is "Note"") # 該條報錯!需對"轉義關于特殊字符及Unicode
# 關于特殊字符及Unicode print("This is \"Note\"") # \ 轉義 print("This is\nNote") # \n 換行 print ("Hello"+u"\u0020"+"World") # u'xxxx':Python2.x unicode對象 = 直接在字符串前加u關鍵字 print("Hello\u0020World") # Python2.x 直接輸出 Hello\u0020World ,Python3.x 會輸出 Hello World
字符串雙引号等特殊字符需轉義,轉義的方法是在 前面加上\;
\n 表示換行
從Python 3.0開始所有的字符串都支持Unicode(參考 )
Unicode 的先進之處在于為每一種現代或古代使用的文字系統中出現的每一個字符都提供了統一的序列号。之前,文字系統中的字符隻能有 256 種可能的順序。通過代碼頁分界映射。文本綁定到映射文字系統的代碼頁。這在軟件國際化的時候尤其麻煩(通常寫作 i18n —— ’i’ + 18 個字符 + ’n’ )。Unicode 解決了為所有的文字系統設置一個獨立代碼頁的難題。
a,b = 0,1 # 變量也可這麼賦值,但不建議 while b < 30: print(b) a,b = b,a+b # 相當于 a=b 和 b = a+b
需要注意的是:縮進
Python開發者有意讓違反了縮進規則的程序不能通過編譯,以此來強制程序員養成良好的編程習慣。并且Python語言利用縮進表示語句塊的開始和退出(Off-side規則),而非使用花括号或者某種關鍵字。增加縮進表示語句塊的開始,而減少縮進則表示語句塊的退出。縮進成為了語法的一部分。同樣的如 if 語句如下:
根據PEP的規定,必須使用4個空格來表示每級縮進(不清楚4個空格的規定如何,在實際編寫中可以自定義空格數,但是要滿足每級縮進間空格數相 等)。使用Tab字符和其它數目的空格雖然都可以編譯通過,但不符合編碼規範。支持Tab字符和其它數目的空格僅僅是為兼容很舊的的Python程序和某些有問題的編輯程序。
不縮進會報錯的例子
a = 2 if a>1: print("a>1") # if 無執行語句會報錯,若需實現if條件下print,參考如下
縮進不對導緻if語句無效的例子
a = 0 if a>1: print("a>1") print("a!=1") # 該語句始終會執行,因為縮進并不在if條件下
縮進不對導緻if語句無效不會報錯,非常容易坑人,改為以下層次if條件生效:
a = 0 if a>1: print("a>1") print("a!=1") # 該語句僅if成立條件下執行
更多格式問題參考:
if語句,當條件成立時運行語句塊。經常與else, elif(相當于else if) 配合使用。
for語句,遍曆列表、字符串、字典、集合等叠代器,依次處理叠代器中的每個元素。
while語句,當條件為真時,循環運行語句塊。
try語句。與except,finally配合使用處理在程序運行中出現的異常情況。
class語句。用于定義類型。
def語句。用于定義函數和類型的方法。
pass語句。表示此行為空,不運行任何操作。
assert語句。用于程序調适階段時測試運行條件是否滿足。
with語句。Python2.6以後定義的語法,在一個場景中運行語句塊。比如,運行語句塊前加密,然後在語句塊運行退出後解密。
yield語句。在叠代器函數内使用,用于返回一個元素。自從Python 2.5版本以後。這個語句變成一個運算符。
raise語句。制造一個錯誤。
import語句。導入一個模塊或包。
from import語句。從包導入模塊或從模塊導入某個對象。
import as語句。将導入的對象賦值給一個變量。
in語句。判斷一個對象是否在一個字符串/列表/元組裡。
Python采用動态類型系統。在編譯的時候,Python不會檢查對象是否擁有被調用的方法或者屬性,而是直至運行時,才做出檢查。所以操作對象時可能會抛出異常。不過,雖然Python采用動态類型系統,它同時也是強類型的。Python禁止沒有明确定義的操作, 比如數字加字符串。
與其它面向對象語言一樣,Python允許程序員定義類型。構造一個對象隻需要像函數一樣調用類型即可。類型本身也是特殊類型type的對象(type類型本身也是type對象),這種特殊的設計允許對類型進行反射編程。
Python内置豐富的數據類型。與Java、C++相比,這些數據類型有效地減少代碼的長度。下面這個列表簡要地描述了Python内置數據類型(适用于Python 3.x):
除了各種數據類型,Python語言還用類型來表示函數、模塊、類型本身、對象的方法、編譯後的Python代碼、運行時信息等等。因此,Python具備很強的動态性。
類型 | 描述 | 例子 | 備注 |
---|---|---|---|
str | 一個由字符組成的不可更改的類型 | “joe” | 在python3裡,字符串由Unicode字符組成 |
bytes | 一個由字節組成的不可更改的類型 | b = b”joe” | |
list | 可以包含多種類型的可改變的類型 | [4.0,”joe”,True] | |
tuple | 可以包含多種類型的不可改變的類型 | {4.0,”joe”,True} | |
set,frozenset | 與數學集合的概念類型,無序,每個元素唯一 | {4.0,”joe”,True},frozenset() | |
dict | 一個可改變的由鍵值對組成的類型 | {4.0,”joe”,True} | |
int | 精度不限的整數 | 66 | |
float | 浮點數,精度與系統相關 | 3.1415927 | |
complex | 複數 | 3+2.7j | |
bool | 邏輯值,真假 | True,False |
+, -, *, /, //, **, ~, %分别表示加法或者取正、減法或者取負、乘法、除法、整除、乘方、取補、取模。 >>, <<表示右移和左移。 &, |, ^表示二進制的AND, OR, XOR運算。 >, <, ==, !=, <=, >=用于比較兩個表達式的值,分别表示大于、小于、等于、不等于、小于等于、大于等于。 在這些運算符裡面,~, |, ^, &, <<, >>必須應用于整數。 使用and, or, not表示邏輯運算 區分列表(list)和元組(tuple)兩種類型;支持列表切割(list slices) 一些Python特有的方法,如 range() lambda 等函數
Python的函數支持遞歸、默認參數值、可變參數,但不支持函數重載。為了增強代碼的可讀性,可以在函數後書寫“文檔字符串”(Documentation Strings,或者簡稱docstrings),用于解釋函數的作用、參數的類型與意義、返回值類型與取值範圍等。可以使用内置函數help()打印出函數的使用幫助。比如: help(randint)
# 函數示例 def my_fun1(): print("hi") my_fun1() # 調用函數 def my_fun2(a): # 函數可帶參數, 參數可為多個 if(a>2): print(">2") my_fun2(3)對象
# 對象示例 class User(object): # Python2.x 需在()内加object;Python3.x 不用加object def __init__(self,name): # 類似于構造函數 self.name=name def print_name(self): print(self.name) u = User("John") # u為一 User對象 print(u.name) # 輸出對象屬性 User.print_name(u) # 調用print_name()函數
有話要說...