VII Python(6)基礎知識(re正規表達式、MySQLdb子產品)
正規表達式RE(regular expression)是一種小型的、高度專業化的程式設計語言,肉嵌在python中,通過re子產品實作;
當發現有問題用正規表達式可解決時,于是将面臨兩個問題;
RE模式被編譯成一系統的位元組碼,再由比對引擎(C寫的)執行,RE語言相對小型和受限(功能有限,并非所有字元串處理都能用RE完成);
re子產品提供了頂級函數調用,常用的有:findall()、sub()、match()、search()、subn()、split();
In [1]: import re
In [2]: re.<TAB>
re.DEBUG re.L re.S re.U re.compile re.findall re.search re.sub
re.DOTALL re.LOCALE re.Scanner re.UNICODE re.copy_reg re.finditer re.split re.subn
re.I re.M re.T re.VERBOSE re.error re.match re.sre_compile re.sys
re.IGNORECASE re.MULTILINE re.TEMPLATE re.X re.escape re.purge re.sre_parse re.template
In [2]: help(re.search) #(search()方法用于在字元串中搜尋模式第一次比對的位置,若有比對到傳回的是對象的記憶體位址,若沒比對到則傳回空)
search(pattern, string, flags=0)
In [3]: help(re.findall) #(findall()将比對到的字元串打包為清單)
findall(pattern, string,flags=0)
Return a list of all non-overlapping matches in the string.
In [4]: help(re.compile)
compile(pattern, flags=0)
Compile a regular expression pattern, returning a pattern object.
In [5]: help(re.finditer)
finditer(pattern, string,flags=0)
Return an iterator over all non-overlapping matches in the
string. For each match, theiterator returns a match object.
In [6]: help(re.subn)
subn(pattern, repl,string, count=0, flags=0)
Return a 2-tuple containing (new_string, number).
In [7]: help(re.match)
match(pattern, string,flags=0)
Try to apply the pattern at the start of the string, returning
amatch object, or None if no match was found.
正則中預設是打開大小寫敏感的,可在标志位處使用re.IGNORECASE取消;
正則中不區分數字,全是字元;
正則預設是貪婪模式,在條件符合時盡可能多的比對,可在.+後加上?進入非貪婪模式即最小比對範圍;
字元比對(普通字元和元字元):
普通字元(大多數字元一般都會和自身比對,例如r'test'會和字元串'test'完全比對);
元字元;
元字元(11個):
. ^ $ * + ? {} [] \ | ()
.點(比對換行符以外的任意字元);
^(比對行首,字元串的開始位置,除非設定标志位re.MULTILINE,在re.MULTILINE模式裡也可比對字元串中的每個換行);
$(比對行尾,行尾被定義為要麼是字元串尾,要麼是一個換行字元後的任何位置);
*(指定前一個字元比對0次或任意次,貪婪模式,比對引擎會嘗試重複盡可能多的次數,不超過整數界定範圍20億);
+(前一個字元比對一次或任意次,預設貪婪模式,若要用非貪婪模式(最小比對模式)+後跟?);
?(比對前一個字元0次或1次,可了解為它用于辨別某事物是可選的);
{m,n}(m和n是十進制整數,前一個字元至少m次重複,最多n次;忽略m則下邊界是0,忽略n則上邊界是無窮大(20億));
[](常用來指定一個字元集,如[abc]、[a-z],元字元在字元集中不起作用;字元集中開始處使用^,補集比對不在區間内的字元);
\num(\後跟不同的字元表示不同的意義;若當作轉義符用可取消元字元本身的意義;\d等同于[0-9],\D等同于[^0-9],\s等同于[\t\n\r\f\v],\S等同于[^\t\n\r\f\v],\w等同于[a-zA-Z0-9_],\W等同于[^a-zA-Z0-9_]
()(分組)
注:
*等同于{0,};+等同于{1,};?等同于{0,1};盡量使用*、+、?這三個符号,因為既美觀而且更關鍵的是正則引擎内部會對這三個符号進行優化,進而執行效率要高,而不要用等同的{0,}、{1,}、{0,1};
*和+差別(*比對的前一個字元可以是0次,+要至少是一次);
[]中的元字元代表其本身,不具備元字元的功能;
\序号(若序号為單個數字,則是引用序号對應的子組所比對的字元串,子組的序号從1開始計算;若序号以0開頭或是3個字元長度時,那麼不會被用于對應的子組,而是用于比對八進制的數字所表示的ASCII表對應的字元);
\A(等同于^,脫字元);
\Z(等同于$)
\b(比對單詞邊界,單詞被定義為Unicode的字母數字或下劃線,注意下劃線也是單詞的一部分);
\B(與\b相反,比對非單詞邊界,例如py\B比對python、py2、py3而不比對py 、py.、py!);
\d(對于Unicode(str類型)模式,比對任何一個數字,包括[0-9]和其它數字字元,若開啟了re.ASCII标志,隻比對[0-9];對于8位模式(bytes類型)比對[0-9]中任何一個數字);
\D(與\d相反,比對任何非Unicode的數字,若開啟了re.ASCII标志,則相當于比對[^0-9]);
\s(對于Unicode(str類型)模式,比對Unicode中的空白字元,包括[\t\n\r\f\v]及其它空白字元,若開啟了re.ASCII标志,隻比對[\t\n\r\f\v];對于8位模式(bytes類型),比對ASCII中定義的空白字元,即[\t\n\r\f\v]);
\S(與\s相反,比對任何非Unicode中的空白字元,若開啟了re.ASCII标志,則相當于比對[^\t\n\f\r\v])
\w(對于Unicode(str類型)模式,比對任何以Unicode的單詞字元,基本上所有語言字元都可比對,也包括數字下劃線[a-zA-Z0-9],若開啟了re.ASCII标志則隻比對[a-zA-Z0-9];對于8位模式(bytes類型),比對ASCII中定義的字母數字);
\W(與\w相反,比對任何非Unicode的單詞字元,若開啟了re.ASCII标志,則相當于[^a-zA-Z0-9]);
轉義符的特殊情況:
\a \b \f \n \r \t \u \U \v \x \\
\b(通常用于單詞邊界,隻有在字元類中才表示backspace);
\u和\U(隻在Unicode模式下才會被識别);
\num(八進制轉義是有限制的,如果第1個數字是0,或如果有3個八進制數字,那麼就被認為是八進制;其它情況則被認為是子組引用;至于字元串,八進制轉義最多隻能是3個數字的長度);
flags标志位:
ASCII(簡寫A,使得轉義符\w、\b、\d、\s隻能比對ASCII字元);
DOTALL(簡寫S,使得.點比對任何符号,包括換行符,無敵狀态);
IGNORECASE(簡寫I,比對時不區分大小寫);
LOCALE(簡寫L,支援目前的語言設定);
MULTILINE(簡寫M,多行比對(要查找的内容為多行),影響^和$);
VERBOSE(簡寫X,啟用詳細的正規表達式,正則的書寫為多行時);
編譯正規表達式:
re子產品提供了一個正規表達式引擎的接口,可将REstring編譯成對象并用它們進行比對;
如果要重複的使用某個正規表達式,可将正規表達式編譯成模式對象,使用re.compile()來編譯;
若隻需查找或比對一次使用子產品級别的方法,如re.findall(r'[A-Z]','string');若要多次使用正規表達式,在循環情況下,就要先編譯再進行調用,這樣使用更友善;
In [6]: help(re.compile)
In [2]: p=re.compile(r'[A-Z]')
In [3]: type(p)
Out[3]: _sre.SRE_Pattern
In [4]: p.search('I love FishC.com')
Out[4]: <_sre.SRE_Match at 0x2bd91d0>
In [5]: p.findall('I love FishC.com')
Out[5]: ['I', 'F', 'C']
In [8]: p.<TAB>
p.findall p.flags p.groups p.pattern p.search p.sub
p.finditer p.groupindex p.match p.scanner p.split p.subn
In [8]: help(p.findall) #(找到RE比對的所有子串,将它們作為清單傳回)
findall(string[, pos[,endpos]]) --> list.
In [10]: print p #(編譯後的正規表達式為對象,可在該對象上應用以上方法,()中直接跟要查找的字元串)
<_sre.SRE_Pattern object at0x268cc10>
In [23]: help(p.finditer) #(找到RE比對的所有子串,将它們作為疊代器傳回)
finditer(string[, pos[,endpos]]) --> iterator.
In [24]: help(p.match) #(決定RE是否在剛開始的位置比對)
match(string[, pos[,endpos]]) --> match object or None.
In [25]: help(p.search) #(掃描字元串,找到這個RE比對的位置)
search(string[, pos[,endpos]]) --> match object or None.
p.match()和p.search()若沒比對到,它們将傳回None,否則傳回MatchObject的執行個體(記憶體位址),MatchObject所支援的方法:group()、start()、end()、span();在實際程式中,最常見的做法是将MatchObject儲存在一個變量裡,檢查是否為None;
In [6]: m=p.match('I love FishC.com!')
In [7]: m.<TAB>
m.end m.expand m.groupdict m.lastgroup m.pos m.regs m.start
m.endpos m.group m.groups m.lastindex m.re m.span m.string
In [7]: help(m.group) #(傳回被RE比對的字元串)
group([group1, ...]) -> str or tuple.
Return subgroup(s) of the match by indices or names.
For 0 returns the entire match.
In [8]: help(m.start) #(傳回比對剛開始的位置)
start([group=0]) -> int.
Return index of the start of the substring matched by group.
In [9]: help(m.end) #(傳回比對結束的位置)
end([group=0]) -> int.
Return index of the end of the substring matched by group.
In [10]: help(m.span) #(傳回一個元組包含比對開始、結束的位置)
span([group]) -> tuple.
For MatchObject m, return the 2-tuple (m.start(group), m.end(group)).
In [20]: p=re.compile(r'[a-z]')
In [21]: m=p.search('I love FishC')
In [22]: m.group()
Out[22]: 'l'
舉例(match()或search()方法在程式中常用來判斷是否比對到):
[root@localhost ~]# vim re_match.py
------------------script start-------------
#!/usr/bin/python2.7
#filename:re_match.py
import re
p=re.compile(r'[a-z]')
m=p.match('string123')
if m:
print 'Match found:',m.group()
else:
print 'No match'
--------------script end----------------
[root@localhost ~]# python2.7 re_match.py
Match found: s
舉例:
In [8]: str1='I love FishC.com!'
In [10]: re.search(r'FishC',str1)
Out[10]: <_sre.SRE_Match at0x24fa648>
In [11]: re.findall(r'FishC',str1)
Out[11]: ['FishC']
In [12]: re.findall(r'.',str1) #(點号表示換行符以外的任意字元,此處全部比對到)
Out[12]:
['I',
' ',
'l',
'o',
'v',
'e',
'F',
'i',
's',
'h',
'C',
'.',
'c',
'm',
'!']
In [13]: re.findall(r'Fish.',str1)
Out[13]: ['FishC']
In [14]: re.findall(r'Fish\.',str1) #(加入轉義符表示元字元本身,此處未比對到内容)
Out[14]: []
In [15]: re.findall(r'\d','I loveFishC.com!123') #(\d表示單個任意數字)
Out[15]: ['1', '2', '3']
In [16]: re.findall(r'\d\d\d','123 456FishC')
Out[16]: ['123', '456']
In [18]: re.findall(r'[aeiou]','string') #([]建立字元類,僅比對中括号中的一個字元)
Out[18]: ['i']
In [19]: re.findall(r'[A-Z]','String') #(正則中預設是打開大小寫敏感的,可用re.IGNORECASE取消)
Out[19]: ['S']
In [20]: re.findall(r'[a-z]','Hello')
Out[20]: ['e', 'l', 'l', 'o']
In [21]:re.findall(r'[a-z]','HELLO',re.IGNORECASE)
Out[21]: ['H', 'E', 'L', 'L', 'O']
In [22]: re.findall(r'ab{3}c','abbbc') #({NUM}表示重複的次數)
Out[22]: ['abbbc']
In [23]: re.findall(r'ab{3,10}c','abbbbc')
Out[23]: ['abbbbc']
In [24]: re.findall(r'[0-255]','188') #(注意此處表示0或1或2後面跟兩個5)
Out[24]: ['1']
In [25]: re.findall(r'[0-255]','1155')
Out[25]: ['1', '1', '5', '5']
In [28]:re.findall(r'(?<![\.\d])(?:\d{1,3}\.){3}\d{1,3}(?![\.\d])','192.168.1.1') #(比對IP)
Out[28]: ['192.168.1.1']
In [29]:re.findall(r'(?<![\.\d])(?:\d{1,3}\.){3}\d{1,3}(?![\.\d])','192.168.23.125')
Out[29]: ['192.168.23.125']
In [30]:re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$','127.0.0.1')
Out[30]: ['127.0.0.1']
In [31]: re.findall(r'Fish(C|D)','www.FishC.com') #(若使用分組(),預設僅顯示比對到的分組内的内容)
Out[31]: ['C']
In [33]: re.findall(r'^FishC','FishC.com')
Out[33]: ['FishC']
In [34]: re.findall(r'FishC$','I loveFishC')
Out[34]: ['FishC']
In [35]:re.findall(r'(FishC)\1','FishCFishC') #(\後跟序号1,引用序号對應的子組所比對的字元串,子組的序号從1開始計算)
Out[35]: ['FishC']
In [36]: re.findall(r'\.','FishC.com') #(\.表示點本身)
Out[36]: ['.']
In [37]: re.findall(r'[.]','FishC.com') #(中括号中的元字元代表其本身,不具備元字元的功能)
Out[37]: ['.']
In [38]: re.findall(r'[\n]','FishC.com\n') #(比對回車符)
Out[38]: ['\n']
In [39]: re.findall(r'[^a-z]','FishC.com') #([]中的^是取反,若取反^隻能放在中括号的最前面)
Out[39]: ['F', 'C', '.']
In [40]: re.findall(r'FishC{3}','FishCCCC') #({NUM}僅對前面的單個字元做重複)
Out[40]: ['FishCCC']
In [41]: re.findall(r'(FishC){2,5}','FishCFishCFishC')
Out[41]: ['FishC']
In [42]:re.findall(r'<.+>','<html><title>I loveFishC</title></html>') #(正則預設是貪婪模式,在條件符合時盡可能多的比對,可在.+後加上?進入非貪婪模式)
Out[42]: ['<html><title>I loveFishC</title></html>']
In [43]:re.findall(r'<.+?>','<html><title>I love FishC</title></html>')
Out[43]: ['<html>', '<title>','</title>', '</html>']
In [46]: re.findall(r'\bFishC\b','FishC.comFishC_com FishC') #(比對單詞邊界,下劃線也是單詞的一部分)
Out[46]: ['FishC', 'FishC']
In [48]: re.findall(r'py\B','python py2py3') #(比對非單詞邊界)
Out[48]: ['py', 'py', 'py']
In [49]: re.findall(r'py\B','py py. py!')
Out[49]: []
In [18]:re.findall(r'^010-?\d{8}','010-12345678')
Out[18]: ['010-12345678']
In [19]: re.findall(r'ab+','abbbbc') #(貪婪模式)
Out[19]: ['abbbb']
In [20]: re.findall(r'ab+?','abbbbbc') #(非貪婪模式,最小比對)
Out[20]: ['ab']
In [23]: re.findall(r'csvt.net','csvt.net')
Out[23]: ['csvt.net']
In [24]:re.findall(r'csvt.net','csvt\nnet')
Out[24]: []
In [25]:re.findall(r'csvt.net','csvt\nnet',re.S) #(開啟了re.DOTALL使得點号可頂替任何字元,包括換行符)
Out[25]: ['csvt\nnet']
舉例(标志位re.M,re.MULTILINE):
In [2]: s='''
...: hello csvt
...: csvt hello
...: '''
In [3]: re.findall(r'^csvt',s) #(不開re.M标志位的情況下,是無法比對多行的)
Out[3]: []
In [4]: re.findall(r'^csvt',s,re.M)
Out[4]: ['csvt', 'csvt']
舉例(标志位re.X,re.VERBOSE,用于正則的書寫為多行時):
In [5]: tel=r'''
...: \d{3,4}
...: -?
...: \d{8}
In [6]: re.findall(tel,'010-12345678')
Out[6]: []
In [7]: re.findall(tel,'010-12345678',re.X)
Out[7]: ['010-12345678']
舉例(分組):
In [8]:re.findall(r'\w{3,}@\w+(\.com|\.cn)','[email protected]') #(當有分組時findall會優先傳回查找到的分組中的内容)
Out[8]: ['.com']
In [9]: re.findall(r'\w{3,}@\w+(\.com|\.cn)','[email protected]')
Out[9]: ['.cn']
In [10]:re.findall(r'\w{3,}@\w+(\.com|\.cn)','[email protected]')
Out[10]: []
In [11]:re.match(r'\w+@\w+(\.com|\.cn)','[email protected]')
Out[11]: <_sre.SRE_Match at0x22e8198>
In [12]: s='''
....: aaa srt hello src=csvt
....: yes
....: hello src=python hello
....: '''
In [13]: re.findall(r'hello src=(.+)',s) #(查找指定内容中包含hello src=……的内容)
Out[13]: ['csvt', 'python hello']
str字元串替換:
In [5]: help(str.replace)
S.replace(old, new[,count]) -> string
In [6]: s='hello csvt'
In [7]: s.replace('csvt','python')
Out[7]: 'hello python'
In [9]: s.replace(r'c..t','python') #(字元串所支援的方法和操作是不支援re的)
Out[9]: 'hello csvt'
re.sub(),re.subn()(正則中的替換):
In [10]: help(re.sub)
sub(pattern, repl,string, count=0, flags=0)
In [11]: help(re.subn)
In [13]: re.sub(r'c..t','csvt','caat cvvt ccct')
Out[13]: 'csvt csvt csvt'
In [14]: re.subn(r'c..t','csvt','caat cvvt ccct') #(subn不僅列印替換的内容,還列印替換了幾次)
Out[14]: ('csvt csvt csvt', 3)
str.split()
In [16]: help(str.split)
S.split([sep[,maxsplit]]) -> list of strings
In [17]: ip='192.168.23.128'
In [18]: ip.split('.')
Out[18]: ['192', '168', '23', '128']
re.split
In [15]: help(re.split)
split(pattern, string,maxsplit=0, flags=0)
In [20]: re.split(r'[\+\-\*]','1+2-3*4') #(中括号中的元字元将失去本身的意義,但此例中-表示範圍,在不加轉義符的前提下,要麼-不能放在兩個元字元中間,要麼将-放到最後即可)
Out[20]: ['1', '2', '3', '4']
In [21]: re.split(r'[+*]','1+2*3')
Out[21]: ['1', '2', '3']
In [22]: re.split(r'[+*-]','1+2-3*4')
Out[22]: ['1', '2', '3', '4']
MySQLdb子產品(軟體包名是MySQL-python-1.2.5.tar.gz):
[root@localhost ~]# yum -y installpython-devel mysql-devel zlib-devel openssl-devel gcc
[root@localhost setuptools-19.6.1]#python2.7 setup.py install (要先安裝setuptools-19.6.1.tar.gz這個子產品)
[root@localhost MySQL-python-1.2.5]#python2.7 setup.py install
……
Installed/usr/local/python2.7/lib/python2.7/site-packages/MySQL_python-1.2.5-py2.7-linux-x86_64.egg
Processing dependencies forMySQL-python==1.2.5
Finished processing dependencies forMySQL-python==1.2.5
注:通過python的MySQLdb子產品與mysql互動,三步驟:
1)建立連接配接、建立遊标,conn=MySQLdb.connect(user='root',password='secret','host'='IP');cur=conn.cursor();
2)選擇庫、發送執行指令進行增删改查操作,conn.select_db('DB');cur.execute('mysqlcommand');
3)關閉,cur.close()、conn.close();
注:增删改查隻用傳遞一次即可,而查詢要兩次(先用cur.execute('select * from table')傳送再用cur.fetchone()檢視記錄),fetchone()每次檢視一條記錄并有指針的移動,可用cur.scroll(0,'absolute')将指針移到剛開始處;
注:查詢也可合并cur.fetchmany(cur.execute('select * form table');
In [1]: import MySQLdb
In [2]: MySQLdb.<TAB>
MySQLdb.BINARY MySQLdb.Timestamp
MySQLdb.Binary MySQLdb.TimestampFromTicks
MySQLdb.Connect MySQLdb.Warning
MySQLdb.Connection MySQLdb.apilevel
MySQLdb.DATE MySQLdb.connect
MySQLdb.DATETIME MySQLdb.connection
MySQLdb.DBAPISet MySQLdb.constants
MySQLdb.DataError MySQLdb.debug
MySQLdb.DatabaseError MySQLdb.escape
MySQLdb.Date MySQLdb.escape_dict
MySQLdb.DateFromTicks MySQLdb.escape_sequence
MySQLdb.Error MySQLdb.escape_string
MySQLdb.FIELD_TYPE MySQLdb.get_client_info
MySQLdb.IntegrityError MySQLdb.paramstyle
MySQLdb.InterfaceError MySQLdb.release
MySQLdb.InternalError MySQLdb.result
MySQLdb.MySQLError MySQLdb.server_end
MySQLdb.NULL MySQLdb.server_init
MySQLdb.NUMBER MySQLdb.string_literal
MySQLdb.NotSupportedError MySQLdb.test_DBAPISet_set_equality
MySQLdb.OperationalError MySQLdb.test_DBAPISet_set_equality_membership
MySQLdb.ProgrammingError MySQLdb.test_DBAPISet_set_inequality
MySQLdb.ROWID MySQLdb.test_DBAPISet_set_inequality_membership
MySQLdb.STRING MySQLdb.thread_safe
MySQLdb.TIME MySQLdb.threadsafety
MySQLdb.TIMESTAMP MySQLdb.times
MySQLdb.Time MySQLdb.version_info
MySQLdb.TimeFromTicks
In [2]: help(MySQLdb.connect)
Connect(*args, **kwargs)
Factory function for connections.Connection.
In [5]: conn.<TAB>
conn.DataError conn.close conn.get_host_info conn.set_character_set
conn.DatabaseError conn.commit conn.get_proto_info conn.set_server_option
conn.Error conn.converter conn.get_server_info conn.set_sql_mode
conn.IntegrityError conn.cursor conn.info conn.show_warnings
conn.InterfaceError conn.cursorclass conn.insert_id conn.shutdown
conn.InternalError conn.default_cursor conn.kill conn.sqlstate
conn.NotSupportedError conn.dump_debug_info conn.literal conn.stat
conn.OperationalError conn.encoders conn.messages conn.store_result
conn.ProgrammingError conn.errno conn.next_result conn.string_decoder
conn.Warning conn.error conn.open conn.string_literal
conn.affected_rows conn.errorhandler conn.ping conn.thread_id
conn.autocommit conn.escape conn.port conn.unicode_literal
conn.begin conn.escape_string conn.query conn.use_result
conn.change_user conn.field_count conn.rollback conn.warning_count
conn.character_set_name conn.get_autocommit conn.select_db
conn.client_flag conn.get_character_set_info conn.server_capabilities
In [5]: help(conn.cursor)
cursor(self,cursorclass=None) method of MySQLdb.connections.Connection instance
Create a cursor on which queries may be performed. The
optional cursorclass parameter is used to create the
Cursor. By default, self.cursorclass=cursors.Cursor is
used.
In [6]: help(conn.select_db)
select_db(...)
Causes the database specified by db to become the default
(current) database on the connection specified by mysql. In subsequent
queries, this database is the default for table references that do not
include an explicit database specifier.
In [8]: cur.<TAB>
cur.DataError cur.NotSupportedError cur.connection cur.fetchmany cur.scroll
cur.DatabaseError cur.OperationalError cur.description cur.fetchone cur.setinputsizes
cur.Error cur.ProgrammingError cur.description_flags cur.lastrowid cur.setoutputsizes
cur.IntegrityError cur.Warning cur.errorhandler cur.messages
cur.InterfaceError cur.arraysize cur.execute cur.nextset
cur.InternalError cur.callproc cur.executemany cur.rowcount
cur.MySQLError cur.close cur.fetchall cur.rownumber
In [32]: help(cur.execute)
execute(self, query,args=None) method of MySQLdb.cursors.Cursor instance
Execute a query.
In [33]: help(cur.executemany)
executemany(self, query,args) method of MySQLdb.cursors.Cursor instance
Execute a multi-row query.
In [34]: help(cur.fetchone)
fetchone(self) method ofMySQLdb.cursors.Cursor instance
Fetches a single row from the cursor. None indicates that
no more rows are available.
In [35]: help(cur.fetchmany)
fetchmany(self,size=None) method of MySQLdb.cursors.Cursor instance
Fetch up to size rows from the cursor. Result set may be smaller
than size. If size is not defined, cursor.arraysize is used.
In [36]: help(cur.scroll)
scroll(self, value,mode='relative') method of MySQLdb.cursors.Cursor instance
Scroll the cursor in the result set to a new position according
to mode.
In [4]:conn=MySQLdb.connect(user='root',passwd='chai',host='127.0.0.1')
In [7]: cur=conn.cursor()
In [8]: conn.select_db('webgame')
In [27]: cur.execute('insert into temp1(accountid,nickname,serverid) value (1,"jowin",14115)')
Out[27]: 1L
In [28]: sqli='insert into temp1(accountid,nickname,serverid) values (%s,%s,%s)'
In [29]: cur.execute(sqli,(2,'snow',14116))
Out[29]: 1L
In [31]:cur.executemany(sqli,[(3,'maisie',14117),(4,'emilia',14118),(5,'lsaac',14119)])
Out[31]: 3L
In [37]: cur.execute('select * from temp1')
Out[37]: 5L
In [38]: cur.fetchone() #(每查詢一條有指針的移動)
Out[38]: (1L, 'jowin', 14115L)
In [39]: cur.fetchone()
Out[39]: (2L, 'snow', 14116L)
In [40]: cur.fetchone()
Out[40]: (3L, 'maisie', 14117L)
In [41]: cur.fetchone()
Out[41]: (4L, 'emilia', 14118L)
In [42]: cur.fetchone()
Out[42]: (5L, 'lsaac', 14119L)
In [43]: cur.fetchone()
In [44]: cur.scroll(0,'absolute') #(将指針移到開始位置)
In [45]: cur.fetchmany(5)
Out[45]:
((1L, 'jowin', 14115L),
(2L,'snow', 14116L),
(3L,'maisie', 14117L),
(4L,'emilia', 14118L),
(5L,'lsaac', 14119L))
In [47]: cur.fetchmany(cur.execute('select* from temp1')) #(查詢兩步合為一步)
Out[47]: