有段時間沒有使用python了,對它的語法有點生疏,花了幾個小時熟悉,期間發現不少小細節不清楚。爲了下次能快速上手,避免重複犯錯,我將python使用過程當中的一些問題在這篇博文中記錄小結一下,主要內容涉及到python操做mysql數據庫,python發送http請求,解析txt文本,解析JSON字符串,crontab執行python腳本,等等。(注:我用的是python2.7版本)python
爲方便操做,建議在系統環境變量path裏面添加python的安裝路徑,好比個人是D:\Python27。mysql
1、添加第三方模塊module,並導入模塊linux
在windowns裏面,能夠先下載模塊對應的包文件,放到python默認的模塊文件夾下(./python2.7/Lib/site-packages/)。而後在cmd中進入模塊的解壓文件,執行python setup.py install。(注意:若是事先沒有添加python安裝路徑到環境變量裏,是不能執行這個命令的)android
在ubuntu裏,以root用戶權限執行 easy_install module_name,即可。sql
在linux系統裏,執行 sudo yum install module_name,即可。shell
有些模塊須要下載對應的壓縮包,解壓後進入包下,找到setup.py,執行數據庫
python#{版本號} setup.py install 進行安裝
python的腳本文件裏面,能夠導入其餘腳本文件,並引用其中的方法和參數,使用關鍵字import。以下:
json
import os,glob,sysubuntu
注意:要想到添加的模塊成功import導入,須要重啓python 的IDLE,不然雖然能夠在cmd命令行成功import,卻不能在IDLE中import,會提示找不到module。windows
2、基礎數據類型和語法
一、普通變量定義
python 做爲腳本型語言,對變量的定義很寬鬆,不用爲變量特定申明其類型,相似於jsp頁面中的變量定義,直接是 變量名=... 便可。
輸出字符和整型變量拼接的內容時,須要把整型轉換成字符型,如
i=10
print 'out:'+i 會報錯:TypeError: cannot concatenate 'str' and 'int' objects
須要更改爲:
print 'out:'+str(i)
二、數組變量定義
數組變量定義,在 = 號後面加上中括號,中括號中能夠指定數組長度。如:phoneList = []。往數組中添加值,用的是數組的append()方法;獲取數組某位的值,用: phoneList[index]便可。獲取數組的長度,能夠用 len(List)方法。數組排序方法:phoneList.sort()
對數組使用 sorted(array),能直接排序數組。若是是字符串類型,則按首字母排序,如:1, 10, 12, 2, 23, 3 ...
三、字典變量的定義
(1)字典定義
dict={} 便可。
獲取字典的全部Kye值: dict.keys()
根據key值取字典value: v=name_dict[key]
判斷某個key是否在字典裏:
a={'a':1,'b':2,'c':3} if 'b' in a: print a['b']
(2)字典排序
按value值大小排序:
ret_list = sorted(d.items(),key=lambda item:item[1])
d.items()表示將字典d轉換成元組列表,key=lambda item:item[1] 表示選取每一個元組中第二個元素做爲比較對象。此時返回的結果是一個元組列表
四、字符串變量
字符串對象包含了一些私有的方法,如
(1)以某類分隔符對字符串進行分割的 .split(';') 方法;去除字符串首位的字符的 .strip('--')方法;
(2)截取字符串一段:sStr1 = sStr2[0:n]
(3)str類型字符串與unicode類型字符串轉換
string和unicode都有decode()和encode()方法。 decode方法是將string轉換成unicode; encode方法是將unicode轉換成string; contentList = " ".join([i for i in jieba.cut(contents)])#unicode類型 print contentList.__class__ contentList = contentList.encode('utf-8') print contentList.__class__
五、異常處理
python可使用try...except處理異常,例如:
sql='select * from table' try: cur.execute('set NAMES utf8') cur.execute(sql) con.commit() except Exception, e: print Exception,":",e print sql
六、python文件頭申明
#!/usr/bin/python #-*- coding:utf-8 -*- #encoding=utf-8 import os,sys reload(sys) sys.setdefaultencoding("utf-8")
七、對象聲明和使用
#定義對象 class LoginObj: app_id='' corp_id='' corp_name='' phone='' #對象使用 loginObj=LoginObj() loginObj.corp_id='aaa' ...
判斷NoneType類型的數據: if st is None: print("st is none")
NoneType類型數據不能用len(st)==0 或 st=='' 來判斷。
3、讀取數據庫表
一、引入MySQLdb包。
windows下,下載這個包的exe文件,直接點擊安裝便可;
linux下,能夠用命令sudo yum install MySQL-python 安裝。
引入包:import MySQLdb as mdb
MySQLdb鏈接mysql數據庫,只在2.x版本中支持,推薦使用2.7版本。
二、鏈接mysql數據庫
須要指定數據庫服務器地址ip、數據庫用戶名和祕密、需訪問的數據庫名以及默認字符編碼。如:
conn = mdb.connect('hostIp','root','view','db_test',charset='utf8') 表示訪問hostIp中的db_test數據庫,用戶名root,密碼view,設置字符編碼是utf8。
因爲mysql默認數據庫服務器端口是3306,若是你的端口不是這個,就須要在鏈接時指定端口(端口號是int 型,不需加引號),如:
conn = mdb.connect('hostIp','user_name','password','db_name',port,charset='utf8')
三、使用遊標,來獲取數據庫查詢結果的每一行
cur = conn.cursor() #先定義一個遊標
sql = "select ..." #定義sql語句
cur.execute("set NAMES utf8") #設定sql語句中的參數的字符編碼是utf8
cur.execute(sql) #執行sql查詢語句。
conn.commit() #提交sql語句,必定要加上。
四、獲取查詢結果中的每一行結果數據
rows = cur.fetchall() #rows是不少行的一個集合
val = row[0] #row 是rows中的一行。使用循環獲取每一行。
4、for循環語句, 子語句必需要縮進一個tab鍵。
退出循環時,語句與for語句塊間隔一行以方便區分。以下:
for row in rows:
print (row[0])
print ("out of for block")
5、操做文件
一、文件路徑,以下:
windows中: path=r'E:\tmp-excel'+'\\' (字符串前的字母‘r’的意思,表示一個原始字符串)
Linux中:file_path='/usr/local/test/'
對於最後一個路徑字符串以 \ 結尾的,須要使用轉義字符形式 '\\',第一個 \ 是轉義標識符,表示接下來的一個字符是真實字符。
二、讀取路徑下的文件和內容,須要導入 os包和glob包。
python使用 os.chdir(path) 跳轉到指定path目錄下;
而後用 glob.glob('*.txt.???'),模糊匹配文件名知足 *.txt??? 格式的文件(*號表示匹配任意個字符,?號表示匹配單個任意字符),並返回文件名的數組對象fileList。
使用 fo = open(fileName) 方法打開文件, lines = fo.readlines() 按行讀取文件所有內容。(ps: 雖然我每行都以 '\r' 字符結尾的,但python可能會將整個文件內容只做爲一行,我就是這種狀況。)爲了得到每一行的數據,我將整個一行用 .split('\r') 進行拆分,再進行處理。
若是須要對路徑下的文件排序後再處理,能夠直接使用數組排序方法fileList.sort(), 對文件名數組排序。
三、更改文件名
os.rename(oldName,newName)
6、提交http請求:
(1)使用httplib2提交http GET請求,並獲取響應數據
import httplib2 url=' httplib2.Http('.cache')#設置使用緩存 h=httplib2.Http()#不使用緩存response,content=h.request(url) print '%s' %(content)
(2)使用httplib提交http POST請求,並獲取響應數據
import httplib def postToNewUser(userJArray,host,port,url,token): headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8','Authorization':'Bearer '+token,'Accept':'application/vnd.yiqiapp-cn.v1+json','User-Agent':'yiqiapp/android/1.0'} conn=httplib.HTTPConnection(host,port) jparam=urllib.urlencode({'action':'import','users':userJArray}) conn.request('POST',url,jparam,headers) rsp=conn.getresponse() data=rsp.read() param=json.loads(data) return param
注:
對於包含漢字、空格和其餘特殊字符的URL,須要進行編碼,使用urllib.quote(param)能夠對指定的參數單獨編碼,如:
urllib.quote('2016-08-01 00:00:00')將時間字符串編碼成:2016-08-01%2000%3A00%3A00
post請求中的參數,使用urllib.urlencode(...)進行封裝成標準格式。
7、python解析json數據
#導入模塊:json import json import httplib2 url='http://api.umeng.com/apps?auth_token=fdsfsdolnmjfsolf' h=httplib2.Http('.cache') response,content=h.request(url) #s是一個數組:[{appkey:xxxx,category:aaaa,name:ddd},{appkey:eee,category:bd,name:kkk}...] s=json.loads(content) print len(s) for i in s: print i['appkey']
#json數組操做 import demjson jvalueList=[] jsonArray=[] jsonObj={} jsonObj['name']=user.name jsonObj['phone']=user.phone try: jsonArray.append(jsonObj) except Exception , e: print 'continue' #print jsonArray[0]['name'] try: #將json數組轉換成字符串,去掉'u'標記 jvalue=demjson.encode(jsonArray) jvalueList.append(jvalue) userNum=userNum+1 except Exception , e: print jvalue
8、在crontab中定時執行python腳本
1. crontab執行定時任務的方法,我就不作過多說明了,就是指定定時執行的時間、需執行的腳本命令。舉個例子,天天8點50分,執行日誌解析的腳本,將結果保存到指定文件中:
50 8 * * * /usr/local/bin/python /root/python_scripts/parse_log.py > /root/results/test.txt &
2. 可能會出現的問題
(1)一個最可能出現的問題就是,上面的語句[/usr/local/bin/python /root/python_scripts/parse_log.py > /root/results/test.txt &] 在shell中執行沒有問題,可是在crontab中卻不能執行,並可能提示某些依賴的module沒法導入:importError: No module named ....
產生這個問題的最可能的緣由是,crontab和shell中執行python時的版本不一致。咱們能夠經過一下方法進行驗證:
首先,在shell中執行:import sys,而後執行print sys.path,從系統路徑當中找到當前shell使用的python版本。
['', '/usr/local/lib/python2.7/site-packages/setuptools-12.0.5-py2.7.egg', '/usr/local/lib/python2.7/site-packages/gunicorn-19.1.1-py2.7.egg'......
而後,在parse_log.py中加入import sys 和 print sys.path 兩行,在crontab中設定定時任務,如舉例中的語句。執行結果可能會以下:
['', '/usr/local/lib/python2.6/site-packages/setuptools-12.0.5-py2.6.egg', '/usr/local/lib/python2.6/site-packages/gunicorn-19.1.1-py2.6.egg'......
咱們發現crontab和shell執行python時引用的版本不一致,而提示沒法加載的模塊可能在某個版本以後才新增進來的,所以出現了沒法加載模塊的問題。
那麼,解決的方法是:在crontab中使用全路徑指定引用的python版本,即:
50 8 * * * /usr/local/bin/python2.7 /root/python_scripts/parse_log.py > /root/results/test.txt &
須要說明的是,爲避免這類問題的出現,咱們在設置crontab定時任務時,最後都使用全路徑。
代碼示例:
此次寫的的代碼以下:
1、讀取txt文件
#!/usr/bin/python #coding=utf-8 # -*- coding: utf-8 -*- import os,glob,sys phoneList = [] path=r'E:\tmp-excel'+'\\' os.chdir(path) sumJ=0 for fname in glob.glob('*.txt'): fo=open(fname) lines=fo.readlines() j=0 print (fname) for line in lines: line=line.split('\r') for l in line: l=l.split(',,') phoneList.append(l[1]) #print (l[1]) j=j+1 print (j) sumJ=sumJ+j print ("total phoneNo is :",len(phoneList)) print ("total phoneNo is :",sumJ)