參考鏈接: Python | a += b并不總是a = a + b
官網http://www.python.org/?
官網library? http://docs.python.org/library/??
PyPI https://pypi.python.org/pypi?
中文手冊,適合快速入門? http://download.csdn.net/detail/xiarendeniao/4236870??
python cook book中文版? http://download.csdn.net/detail/XIARENDENIAO/3231793??
??
1.數值尤其是實數很方便、字符串操作很炫、列表? ? ?a = complex(1,0.4)
? ? ?a.real
? ? ?a.imag
?
? ? Unicode()?
? ? 字符串前加上r/R表示常規字符串,加上u/U表示unicode字符串? ? ? 列表的append()方法在列表末尾加一個新元素
?
?2.流程控制
?
while:
if:
? ? if xxx:
? ? ? ? ...
? ? elif yyy:
? ? ? ? ...
? ? elif xxx:
? ? ? ? ...
? ? else:
? ? ? ? ...
for
range()
break? continue? 循環中的else
pass
?3.函數
? ? ?1)def? funA(para)? ? 沒有return語句時函數返回None,參數傳遞進去的是引用
? ? ?2)默認參數,默認參數是列表、字典、類實例時要小心
? ? ?3)不定參數,def? funB(king, *arguments, **keywords) 不帶關鍵字的參數值存在元組arguments中,關鍵字跟參數值存在字典keywords中。其實是元組封裝和序列拆封的一個結合。
? ? ?4)
def? funC(para1, para2, para3) 下面的調用把列表元素分散成函數參數funcC(*list)
?
? ? 5)匿名函數 lambda arg1,arg2...:<expression>?
? ? ? ? 特點:創建一個函數對象,但是沒有賦值給標識符(不同于def);lambda是表達式,不是語句;“:”后面只能是一個表達式? ? ? 6)if? ‘ok’? in? (‘y’, ‘ye’, ‘yes’): xxxxx 關鍵字in的用法
? ? ?7)f = bambda x: x*2 等效于 def f(x): return x*2
?
?4.數據結構
? ? ?1)[] help(list) append(x) extend(L) insert(i,x) remove(x) pop([i]) index(x) count(x) sort() reverse()
? ? ?2)List的函數化編程 filter()? map()? reduce()
? ? ?3)列表推導式 aimTags = [aimTag for aimTag in aimTags if aimTag not in filterAimTags]
? ? ?4)del刪除列表切片或者整個變量
? ? ?5)() help(tuple) 元組tuple,其中元素和字符串一樣不能改變。元組、字符串、列表都是序列。 Python 要求單元素元組中必須使用逗號,以此消除與圓括號表達式之間的歧義。這是新手常犯的錯誤
? ? ?6){} help(dict) 字典 keys() has_key() 可用以鍵值對元組為元素的列表直接構造字典
? ? ?7)循環 字典:for k, v in xxx.iteritems():… for item in xxx.items():... 序列:for i, v in enumerate([‘tic’, ‘tac’, ‘toe’]):… 同時循環多個序列:for q, a in zip(questions, answers):…
? ? ?8)in? ? not in? ? is? ? is not? ? a<b==c? ? and? ? ?or? ? not
? ? ?9)相同類型的序列對象之間可以用< > ==進行比較
?
? ? 10)判斷變量類型的兩種方法:isinstance(var,int) type(var).__name__=="int"??
? ? ? ? ? 多種類型判斷,isinstance(s,(str,unicode))當s是常規字符串或者unicode字符串都會返回True??
? ? 11)在循環中刪除list元素時尤其要注意出問題,for i in listA:... listA.remove(i)是會有問題的,刪除一個元素之后后面的元素就前移了;for i in len(listA):...del listA[i]也會有問題,刪除元素后長度變化,循環會越界?
? ? ? ? ? ? filter(lambda x:x !=4,listA)這種方式比較優雅?
? ? listA = [ i for i in listA if i !=4] 也不錯,或者直接創建一個新的列表算球? ? ? 效率:
? ? ?1)"if k in my_dict" 優于 "if my_dict.has_key(k)"
?
? ? 2)"for k in my_dict" 優于 "for k in my_dict.keys()",也優于"for k in [....]"?
12)set是dict的一種實現? https://docs.python.org/2/library/stdtypes.html#set-types-set-frozenset??
?
>>> s1 = set([1,2,3,4,5])?
>>> s2 = set([3,4,5,6,7,8])?
>>> s1|s2
set([1, 2, 3, 4, 5, 6, 7, 8])
>>> s1-s2
set([1, 2])
>>> s2-s1
set([8, 6, 7])
?
?
?5.模塊
? ? ?1)模塊名由全局變量__name__得到,文件fibo.py可以作為fibo模塊被import fibo導入到其他文件或者解釋器中,fibo.py中函數明明必須以fib開頭
? ? ?2)import變體: from fibo import fib, fib2 然后不用前綴直接使用函數
? ? ?3)sys.path? ? sys.ps1? ? sys.ps2
? ? ?4)內置函數 dir() 用于按模塊名搜索模塊定義,它返回一個字符串類型的存儲列表,列出了所有類型的名稱:變量,模塊,函數,等等
? ? ? ?help()也有類似的作用
? ? ?5)包 import packet1.packet2.module? ? ? ? from packet1.packet2 import module? ? ? ? from packet1.packet2.module import functionA
? ? ?6)import 語句按如下條件進行轉換:執行 from package import * 時,如果包中的 __init__.py 代碼定義了一個名為 __all__ 的列表,就會按照列表中給出的模塊名進行導入
? ? ?7)sys.path打印出當前搜索python庫的路徑,可以在程序中用sys.path.append("/xxx/xxx/xxx")來添加新的搜索路徑
? ? ?8)安裝python模塊時可以用easy_install,卸載easy_install -m pkg_name
? ? ?9)用__doc__可以得到某模塊、函數、對象的說明,用__name__可以得到名字(典型用法:if __name__=='__main__': ...)
?
?6.IO
?
? ? 1)str() unicode()? repr()? repr()? print? rjust()? ljust()? center()? zfill()? xxx%v? xxx%(v1,v2) 打印復雜對象時可用pprint模塊(調試時很有用)?
? ? ? 對于自定義的類型,要支持pprint需要提供__repr__方法。對于pprint的結果不想直接給標準輸出(pprint.pprint(var))可以用pprint.pformat(var).? ? ? 2)f = open(“fileName”, “w”) w r a r+? Win和Macintosh平臺還有一個模式”b”
? ? ? ?f.read(size)
? ? ? ?f.readline()
? ? ? ?f.write(string)
? ? ? ?f.writelines(list)
? ? ? ?f.tell()
? ? ? ?f.seek(offset, from_what) from_what:0開頭 1當前 2末尾 offset:byte數http://www.linuxidc.com/Linux/2007-12/9644p3.htm
? ? ? ?f.close()
? ? ? ?
?
? ? ? linecache模塊可以方便的獲取文件某行數據,在http-server端使用時要注意,尤其是操作大文件很危險,并發情況下很容易就讓機器內存耗盡、系統直接掛掉(本人血的教訓)?
? ? ? 文件操作時shutil比較好用?
? ? ? ?os.walk()遍歷目錄下所有文件??
? ? ?3)pickle模塊(不是只能寫入文件中)
? ? ?封裝(pickling)類似于php的序列化:pickle.dump(objectX, fileHandle)
? ? ?拆封(unpickling)類似于php反序列化:objectX = pickle.load(fileHandle)
?
? ? ?
msgpack(easy_install msgpack-python)比pickle和cpickle都好用一些,速度較快
? ? ?msgpack.dump(my_var, file('test_file_name','w'))
? ? ?msgpack.load(file('test_file_name','r'))
?
?
? ? 4)raw_input()接受用戶輸入 7.class
? ? ?1)以兩個下劃線下頭、以不超過一個下劃線結尾成員變量和成員函數都是私有的,父類的私有成員在子類中不可訪問
?
? ? 2)調用父類的方法:1>ParentClass.FuncName(self,args) 2>super(ChildName,self).FuncName(args) 第二種方法的使用必須保證類是從object繼承下來的,否則super會報錯?
? ? 3)靜態方法定義,在方法名前一行寫上@staticmethod。可以通過類名直接調用。??
?
#!/bin/python
#encoding=utf8
class A(object):
? ? ? ? def __init__(self, a, b):
? ? ? ? ? ? ? ? self.a = a
? ? ? ? ? ? ? ? self.b = b
? ? ? ? def show(self):
? ? ? ? ? ? ? ? print "A::show() a=%s b=%s" % (self.a,self.b)
?
class B(A):
? ? ? ? def __init__(self, a, b, c):
? ? ? ? ? ? ? ? #A.__init__(self,a,b)
? ? ? ? ? ? ? ? super(B,self).__init__(a,b) #super這種用法要求父類必須是從object繼承的
? ? ? ? ? ? ? ? self.c = c
?
if __name__ == "__main__":
? ? ? ? b = B(1,2,3)?
? ? ? ? print b.a,b.b,b.c
? ? ? ? b.show()
?
#輸出
xudongsong@sysdev:~$ python class_test.py?
1 2 3
A::show() a=1 b=2
?8.編碼
? ? ?常見的編碼轉換分為以下幾種情況:
?
? ? ? ? ?unicode->其它編碼
? ? ? ? ?例如:a為unicode編碼 要轉為gb2312。a.encode('gb2312')
?
? ? ? ? ?其它編碼->unicode
? ? ? ? ?例如:a為gb2312編碼,要轉為unicode。 unicode(a, 'gb2312')或a.decode('gb2312')
?
? ? ? ? ?編碼1 -> 編碼2
? ? ? ? ?可以先轉為unicode再轉為編碼2
?
? ? ? ? ?如gb2312轉big5
? ? ? ? ?unicode(a, 'gb2312').encode('big5')
?
? ? ? ? ?判斷字符串的編碼
? ? ? ? ?isinstance(s, str) 用來判斷是否為一般字符串
? ? ? ? ?isinstance(s, unicode) 用來判斷是否為unicode
?
? ? ? ? 如果一個字符串已經是unicode了,再執行unicode轉換有時會出錯(并不都出錯)?
?
>>> str2 = u"sfdasfafasf"
>>> type(str2)
<type 'unicode'>
>>> isinstance(str2,str)
False
>>> isinstance(str2,unicode)
True
>>> type(str2)
<type 'unicode'>
>>> str3 = "safafasdf"
>>> type(str3)? ? ? ??
<type 'str'>
>>> isinstance(str3,unicode)
False
>>> isinstance(str3,str)? ??
True
>>> str4 = r'asdfafadf'
>>> isinstance(str4,str)
True
>>> isinstance(str4,unicode)
False
>>> type(str4)
<type 'str'>
?可以寫一個通用的轉成unicode函數:
? ? ? ? ?def u(s, encoding):
? ? ? ? ? ? ?if isinstance(s, unicode):
? ? ? ? ? ? ? ? ?return s
? ? ? ? ? ? ?else:
? ? ? ? ? ? ? ? ?return unicode(s, encoding)
? ? ?
?9.線程
? ? ?1)要讓子線程跟著父線程一起退出,可以對子線程調用setDaemon()
? ? ?2)對子線程調用join()方法可以讓父線程等到子線程退出之后再退出
?
? ? 3)ctrl+c只能被父線程捕獲到(子線程不能調用信號捕獲函數signal.signal(signal,function)),對子線程調用join()會導致父線程捕獲不到ctrl+c,需要子線程退出后才能捕獲到?
附:成應元老師關于python信號的郵件 參考? http://stackoverflow.com/questions/631441/interruptible-thread-join-in-python From? http://docs.python.org/library/signal.html#module-signal: Some care must be taken if both signals and threads are used in the same program. The fundamental thing to remember in using signals and threads simultaneously is: always perform signal() operations in the main thread of execution. Any thread can perform an alarm(), getsignal(), pause(), setitimer() or getitimer(); only the main thread can set a new signal handler, and the main thread will be the only one to receive signals (this is enforced by the Python signal module, even if the underlying thread implementation supports sending signals to individual threads). This means that signals can’t be used as a means of inter-thread communication. Use locks instead. 總是在主線程調用signal設置信號處理器,主線程將是唯一處理信號的線程。因此不要把線程間通信寄托在信號上,而應該用鎖。 The second, from http://docs.python.org/library/thread.html#module-thread: Threads interact strangely with interrupts: the KeyboardInterrupt exception will be received by an arbitrary thread. (When the signal module is available, interrupts always go to the main thread.) 當導入signal模塊時, KeyboardInterrupt異常總是由主線程收到,否則KeyboardInterrupt異常會被任意一個線程接到。 直接按Ctrl+C會導致Python接收到SIGINT信號,轉成KeyboardInterrupt異常在某個線程拋出,如果還有線程沒有被 setDaemon,則這些線程照運行不誤。如果用kill送出非SIGINT信號,且該信號沒設置處理函數,則整個進程掛掉,不管有多少個線程 還沒完成。??
下面是signal的一個使用范例:??
?
>>> import signal
>>> def f():
...? ? ?signal.signal(signal.SIGINT, sighandler)
...? ? ?signal.signal(signal.SIGTERM, sighandler)
...? ? ?while True:
...? ? ? ? ? ? ?time.sleep(1)
...?
>>> def sighandler(signum,frame):
...? ? ?print signum,frame
...?
>>> f()
^C2 <frame object at 0x15b2a40>
^C2 <frame object at 0x15b2a40>
^C2 <frame object at 0x15b2a40>
^C2 <frame object at 0x15b2a40>?
??
signal的設置和清除:?
?
import signal, time
?
term = False
?
def sighandler(signum, frame):
? ? ? ? print "terminate signal received..."
? ? ? ? global term
? ? ? ? term = True
?
def set_signal():
? ? ? ? signal.signal(signal.SIGTERM, sighandler)
? ? ? ? signal.signal(signal.SIGINT, sighandler)
?
def clear_signal():
? ? ? ? signal.signal(signal.SIGTERM, 0)
? ? ? ? signal.signal(signal.SIGINT, 0)
?
?
set_signal()
while not term:
? ? ? ? print "hello"
? ? ? ? time.sleep(1)
?
print "jumped out of while loop"
?
clear_signal()
term = False
for i in range(5):
? ? ? ? if term:
? ? ? ? ? ? ? ? break
? ? ? ? else:
? ? ? ? ? ? ? ? print "hello, again"
? ? ? ? ? ? ? ? time.sleep(1)?
?
?
[dongsong@bogon python_study]$ python signal_test.py?
hello
hello
hello
^Cterminate signal received...
jumped out of while loop
hello, again
hello, again
^C
[dongsong@bogon python_study]$ 多進程程序使用信號時,要想讓父進程捕獲信號并對子進程做一些操作,應該在子進程啟動完成以后再注冊信號處理函數,否則子進程繼承父進程的地址空間,也會有該信號處理函數,程序會混亂不堪?
?
from multiprocessing import Process, Pipe
import logging, time, signal
?
g_logLevel = logging.DEBUG
g_logFormat = "%(asctime)s %(levelname)s [%(filename)s:%(lineno)d]%(message)s"
?
def f(conn):
? ? conn.send([42, None, 'hello'])
? ? #conn.close()
? ? logging.basicConfig(level=g_logLevel,format=g_logFormat,stream=None)
? ? logging.debug("hello,world")
?
def f2():
? ? while True:
? ? ? ? print "hello,world"
? ? ? ? time.sleep(1)
?
termFlag = False
def sighandler(signum, frame):
? ? print "terminate signal received..."
? ? global termFlag
? ? termFlag = True
?
if __name__ == '__main__':
#? ? parent_conn, child_conn = Pipe()
#? ? p = Process(target=f, args=(child_conn,))
#? ? p.start()
#? ? print parent_conn.recv()? ?# prints "[42, None, 'hello']"
#? ? print parent_conn.recv()
#? ? p.join()
?
? ? p = Process(target=f2)
? ? p.start()
? ? signal.signal(signal.SIGTERM, sighandler)
? ? signal.signal(signal.SIGINT, sighandler)
?
? ? while not termFlag:
? ? ? ? time.sleep(0.5)
? ? print "jump out of the main loop"
? ? p.terminate()
? ? p.join()?
?
?
10.Python 的內建函數locals() 。它返回的字典對所有局部變量的名稱與值進行映射? ? ??
?
11.擴展位置參數?
def func(*args): ...??
在參數名之前使用一個星號,就是讓函數接受任意多的位置參數。?
python把參數收集到一個元組中,作為變量args。顯式聲明的參數之外如果沒有位置參數,這個參數就作為一個空元組。?
關聯item 3.4??
? ? ??
12.擴展關鍵字參數(擴展鍵參數)?
def accept(**kwargs): ...??
python在參數名之前使用2個星號來支持任意多的關鍵字參數。?
注意:kwargs是一個正常的python字典類型,包含參數名和值。如果沒有更多的關鍵字參數,kwargs就是一個空字典。?
位置參數和關鍵字參數參考這篇文章:http://blog.csdn.net/qinyilang/article/details/5484415? ? ? ??
?
>>> def func(arg1, arg2 = "hello", *arg3, **arg4):
...? ? ?print arg1
...? ? ?print arg2
...? ? ?print arg3
...? ? ?print arg4
...?
?
>>> func("xds","t1",t2="t2",t3="t3")
xds
t1
()
{'t2': 't2', 't3': 't3'}
?
13.裝飾器 在函數前加上@another_method,用于對已有函數做包裝、前提檢查=工作,這篇文章寫得很透徹? http://daqinbuyi.iteye.com/blog/1161274??
??
14.異常處理的語法?
?
import sys
?
try:
? ? f = open('myfile.txt')
? ? s = f.readline()
? ? i = int(s.strip())
except IOError, (errno, strerror):
? ? print "I/O error(%s): %s" % (errno, strerror)
except ValueError:
? ? print "Could not convert data to an integer."
except:
? ? print "Unexpected error:", sys.exc_info()[0]
? ? raise
?
??
>>> try:
...? ? raise Exception('spam', 'eggs')
... except Exception, inst:
...? ? print "error %s" % str(e)
...? ? print type(inst)? ? ?# the exception instance
...? ? print inst.args? ? ? # arguments stored in .args
...? ? print inst? ? ? ? ? ?# __str__ allows args to printed directly
...? ? x, y = inst? ? ? ? ? # __getitem__ allows args to be unpacked directly
...? ? print 'x =', x
...? ? print 'y =', y
...
<type 'instance'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
?
?
?
15.命令行參數的處理,用python的optparse庫處理,具體用法見這篇文章? http://blog.chinaunix.net/space.php?uid=16981447&do=blog&id=2840082?
?
from optparse import OptionParser
[...]
def main():
? ? usage = "usage: %prog [options] arg"
? ? parser = OptionParser(usage)
? ? parser.add_option("-f", "--file", dest="filename",
? ? ? ? ? ? ? ? ? ? ? help="read data from FILENAME")
? ? parser.add_option("-v", "--verbose",
? ? ? ? ? ? ? ? ? ? ? action="store_true", dest="verbose")
? ? parser.add_option("-q", "--quiet",
? ? ? ? ? ? ? ? ? ? ? action="store_false", dest="verbose")
? ? [...]
? ? (options, args) = parser.parse_args()
? ? if len(args) != 1:
? ? ? ? parser.error("incorrect number of arguments")
? ? if options.verbose:
? ? ? ? print "reading %s..." % options.filename
? ? [...]
?
if __name__ == "__main__":
? ? main()通俗的講,make_option()和add_option()用于創建對python腳本的某個命令項的解析方式,用parse_args()解析后單個參數存入args元組,鍵值對參數存入options;dest指定鍵值對的key,不寫則用命令的長名稱作為key;help用于對腳本調用--help/-h時候解釋對應命令;action描述參數解析方式,默認store表示命令出現則用dest+后跟的value存入options,store_true表示命令出現則以dest+True存入options,store_false表示命令出現則以dest+False存入options
?
??
16.最近用了BeautifulSoup v4,出現如下錯誤(之前用的是低版本的BeautifulSoup,沒遇到這個錯誤)?
?
HTMLParser.HTMLParseError: malformed start tag解決辦法:用easy_install html5lib,安裝html5lib,替代HTMLParser
?
參考:http://topic.csdn.net/u/20090531/09/956454dd-ba13-4fa3-af3c-6bf7af5726dc.html?
beautifulsoup官網:http://www.crummy.com/software/BeautifulSoup/??
beautifulsoup的手冊:http://www.crummy.com/software/BeautifulSoup/bs4/doc/?
中文手冊(用于快速入門):http://www.leeon.me/upload/other/beautifulsoup-documentation-zh.html?
下面是一個beautifulsoup的一些用法?
?
[dongsong@localhost boosenspider]$ vpython
Python 2.6.6 (r266:84292, Dec? 7 2011, 20:48:22)?
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>?
>>>?
>>> from bs4 import BeautifulSoup as soup
>>> s = soup('<li class="dk_dk" id="dkdk"><a href="javascript:;" οnclick="MOP.DZH.clickDaka();" class="btn_dk">打卡</a></li>')
>>> s
<html><head></head><body><li class="dk_dk" id="dkdk"><a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">?‰“?�?</a></li></body></html>
>>> type(s)
<class 'bs4.BeautifulSoup'>
>>>?
>>>?
>>> t = s.body.contents[0]
>>> t
<li class="dk_dk" id="dkdk"><a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">?‰“?�?</a></li>
>>> import re
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dks")})
[]
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk")})?
[<a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">?‰“?�?</a>]
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk"),'href':None})
[]
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk"),'href':re.compile('')})
[<a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">?‰“?�?</a>]
>>> t.contents[0]
<a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">?‰“?�?</a>
>>> t.contents[0].string = "hello"
>>> t
<li class="dk_dk" id="dkdk"><a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">hello</a></li>
>>> t.contents[0].text
u'hello'
>>> t.contents[0].string
u'hello'
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk"),'text':re.compile('')})
[]
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk"),'text':re.compile('h')})
[]
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk"),'text':re.compile('^h')})
[]
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk")})? ? ? ? ? ? ? ? ? ? ? ??
[<a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">hello</a>]
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk")},text=re.compile(r''))?
[<a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">hello</a>]
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk")},text=re.compile(r'a'))? ?
[]
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk")},text=re.compile(r'^hell'))?
[<a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">hello</a>]
>>> t.findAll(name='a',attrs={'class':re.compile(r"btn_dk")},text=re.compile(r'^hello$'))
[<a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">hello</a>]
>>>?
>>> t.findAll(name='a',attrs={},text=re.compile(r'^hello$'))? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
[<a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">hello</a>]
>>>?
>>> t
<li class="dk_dk" id="dkdk"><a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">hello</a></li>
>>> t1 = soup('<li class="dk_dk" id="dkdk"><a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">hello</a></li>').body.contents[0]
>>>?
>>> t1
<li class="dk_dk" id="dkdk"><a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">hello</a></li>
>>> t == t1
True
>>> re.search(r'(^hello)|(^bbb)','hello')
<_sre.SRE_Match object at 0x25ef718>
>>> re.search(r'(^hello)|(^bbb)','hellosdfsd')
<_sre.SRE_Match object at 0x25ef7a0>
>>> re.search(r'(^hello)|(^bbb)','bbbsdfsdf')?
<_sre.SRE_Match object at 0x25ef718>
>>> t2 = t1.contents[0]
>>> t2
<a class="btn_dk" href="javascript:;" οnclick="MOP.DZH.clickDaka();">hello</a>
>>> t2.findAll(name='a')
[]?
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>?
>>>?
>>> from bs4 import BeautifulSoup as soup
>>> s = soup('<li><a href="http://www.tianya.cn/techforum/articleslist/0/24.shtml" id="item天涯婚禮堂">天涯婚禮堂</a></li>')?
>>> s.findAll(name='a',attrs={'href':None})
[]
>>> s.findAll(name='a',attrs={'href':True})
[<a href="http://www.tianya.cn/techforum/articleslist/0/24.shtml" id="item?¤???ˉ????¤????">?¤???ˉ????¤????</a>]
>>> import re
>>> s.findAll(name='a',attrs={'href':re.compile(r'')})
[<a href="http://www.tianya.cn/techforum/articleslist/0/24.shtml" id="item?¤???ˉ????¤????">?¤???ˉ????¤????</a>]
>>> s1 =s
>>> s1
<html><head></head><body><li><a href="http://www.tianya.cn/techforum/articleslist/0/24.shtml" id="item?¤???ˉ????¤????">?¤???ˉ????¤????</a></li></body></html>
>>> id(s1)
140598579280080
>>> id(s)
140598579280080
>>> s1.body.contents[0].contents[0]['href']=None
>>> s1
<html><head></head><body><li><a href id="item?¤???ˉ????¤????">?¤???ˉ????¤????</a></li></body></html>
>>> s
<html><head></head><body><li><a href id="item?¤???ˉ????¤????">?¤???ˉ????¤????</a></li></body></html>
>>> id(s)
140598579280080
>>> id(s1)
140598579280080
>>> s.findAll(name='a',attrs={'href':re.compile(r'')})
[]
>>> s.findAll(name='a',attrs={'href':True})? ? ? ? ? ?
[]
>>> s.findAll(name='a',attrs={'href':None})
[<a href id="item?¤???ˉ????¤????">?¤???ˉ????¤????</a>]
>>> s.findAll(name='a')? ? ? ? ? ? ? ? ? ??
[<a href id="item?¤???ˉ????¤????">?¤???ˉ????¤????</a>]
<code><a target=_blank target="_blank" name="arg-text"></a>#text是一個用于搜索<code>NavigableString</code>對象的參數。它的值可以是字符串,一個正則表達式,一個list或dictionary,<code>True</code>或<code>None</code>,一個以<code>NavigableString</code>為參數的可調用對象</code>
#None,False,''表示不做要求;re.compile(''),True表示必須有NavigableString存在 (跟attrs不同,attrs字典中指定為False的屬性表示不能存在)
?#注意findAll函數text參數的使用,如下:
>>> rts = s2.findAll(name=u'ul',attrs={u'id': u'contentbar', u'st_type': 'nav'}, text=re.compile(r''))
>>> len(rts)
0
>>> rts = s2.findAll(name=u'ul',attrs={u'id': u'contentbar', u'st_type': 'nav'}, text='')
>>> len(rts)
1
>>> rts = s2.findAll(name=u'ul',attrs={u'id': u'contentbar', u'st_type': 'nav'}, text=True)
>>> len(rts)
0
>>> rts = s2.findAll(name=u'ul',attrs={u'id': u'contentbar', u'st_type': 'nav'}, text=False)
>>> len(rts)
1
>>> rts = s2.findAll(name=u'ul',attrs={u'id': u'contentbar', u'st_type': 'nav'}, text=None)?
>>> len(rts)
1?
#關于string屬性的用法,以及其在什么類型元素上出現的問題
>>> from bs4 import BeautifulSoup as soup
>>> soup1 = soup('<b>hello,<img href="sfdsf">aaaa</img></b>').body.contents[0]
>>> soup1
<b>hello,<img href="sfdsf"/>aaaa</b>
>>> soup1.string
>>> soup1.name
u'b'
>>> soup1.text
u'hello,aaaa'
>>> type(soup1)
<class 'bs4.element.Tag'>
>>> soup1.contents[0]
u'hello,'
>>> type(soup1.contents[0])
<class 'bs4.element.NavigableString'>
>>> soup1.contents[0].string
u'hello,'
>>> soup2 = soup('<b>hello</b>').body.contents[0]
>>> type(soup2)
<class 'bs4.element.Tag'>
>>> soup2.string
u'hello'
#limit的用法,為零表示不限制
>>> soup2.findAll(name='a',text=False,limit=0)
[<a href="http://book.douban.com/subject/4172417/"><img class="m_sub_img" src="http://img1.douban.com/spic/s4424194.jpg"/></a>, <a href="http://book.douban.com/subject/4172417/">??????é?£?1′</a>]
>>> soup2.findAll(name='a',text=False,limit=1)
[<a href="http://book.douban.com/subject/4172417/"><img class="m_sub_img" src="http://img1.douban.com/spic/s4424194.jpg"/></a>]?
?
BeautifulSoup的性能一般,但是對于不合法的hetml標簽有很強的修復和容錯能力,對于編碼問題,能確定來源頁面編碼的情況下可以通過BeautifulSoup的構造函數(參數from_encoding)指定(如我解析天涯的頁面時就指定了from_encoding='gbk'),不確定來源的話可以依賴bs的自動編碼檢測和轉換(可能會有亂碼,畢竟機器沒人這么聰明)。?
BeautifulSoup返回的對象、以及其各節點內的數據都是其轉換后的unicode編碼。?
??
---------->?
今天遇到一個小問題?
有一段html源碼在bs3.2.1下構建bs對象失敗,拋出UnicodeEncodeError,不論把源碼用unicode還是utf-8或者lantin1傳入都報錯,而且bs3.2.1構造函數居然沒有from_encoding的參數可用?
尼瑪,在bs4下就暢行無阻,不論用unicode編碼傳入還是utf-8編碼傳入,都不用指定from_encoding(編碼為utf-8、不指定from_encoding時出現亂碼,但是也沒有報錯呀,誰有bs3那么脆弱啊!)?
總結一個道理,代碼在某個版本庫下面測試穩定了以后用的時候安裝相應版本的庫就ok了,為嘛要委曲求全的做兼容,如果低版本的庫有bug我也兼容嗎?兼?賤!??
<--------------------2012-06-08 18:20?
??
bs4構建對象:?
?
[dongsong@bogon boosenspider]$ cat bs_constrator.py? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
#encoding=utf-8
?
from bs4 import BeautifulSoup as soup
from bs4 import Tag
?
if __name__ == '__main__':
? ? ? ? sou = soup('<div></div>')
?
? ? ? ? tag1 = Tag(sou, name='div')
? ? ? ? tag1['id'] = 'gentie1'
? ? ? ? tag1.string = 'hello,tag1'
? ? ? ? sou.div.insert(0,tag1)
?
? ? ? ? tag2 = Tag(sou, name='div')
? ? ? ? tag2['id'] = 'gentie2'
? ? ? ? tag2.string = 'hello,tag2'
? ? ? ? sou.div.insert(1,tag2)
?
? ? ? ? print sou
[dongsong@bogon boosenspider]$ vpython bs_constrator.py
<html><head></head><body><div><div id="gentie1">hello,tag1</div><div id="gentie2">hello,tag2</div></div></body></html>?
cgi可以對html字符串轉義(escape);HTMLParser可以取消html的轉義(unescape)?
?
>>> t = Tag(name='t')? ? ? ? ? ? ? ? ? ? ? ? ? ??
>>> t.string="<img src='www.baidu.com'/>"? ? ? ? ? ? ? ? ? ? ? ? ??
>>> t
<t><img src='www.baidu.com'/></t>
>>> str(t)
"<t><img src='www.baidu.com'/></t>"
>>> t.string
u"<img src='www.baidu.com'/>"
>>> HTMLParser.HTMLParser().unescape(str(t))
u"<t><img src='www.baidu.com'/></t>"
>>> s1
u"<t><img src='www.baidu.com'/></t>"
>>>?
>>> s2 = cgi.escape(s1)
>>> s2
u"<t><img src='www.baidu.com'/></t>"
>>> HTMLParser.HTMLParser().unescape(s2)
u"<t><img src='www.baidu.com'/></t>"
?
?
?17.加密md5模塊或者hashlib模塊?
?
?
>>> md5.md5("asdfadf").hexdigest()
'aee0014b14124efe03c361e1eed93589'
>>> import hashlib
>>> hashlib.md5("asdfadf").hexdigest()
'aee0014b14124efe03c361e1eed93589'
?
18.urllib2.urlopen(url)不設置超時的話可能會一直等待遠端服務器的反饋,導致卡死?
?
urlFile = urllib2.urlopen(url, timeout=g_url_timeout)
urlData = urlFile.read()
?
19.正則匹配? re模塊??
? ? ? 用三個單引號括起來的字符串可以跨行,得到的實際字符串里面有\n,這個得注意?
? ? ? 用單引號或者雙引號加上\也可以實現字符串換行,得到的實際字符串沒有\和\n,但是在做正則匹配時寫正則串不要用這種方式寫,會匹配不上的?
?
>>> ss = '''
... hell0,a
... shhh
... liumingdong
... xudongsong
... hello
... '''
>>> ss
'\nhell0,a\nshhh\nliumingdong\nxudongsong\nhello\n'
SyntaxError: EOL while scanning string literal
>>> sss = 'aaaa\
... bbbb\
... cccccc'
>>> sss
'aaaabbbbcccccc'
>>> s3 = r'(^hello)|\
... (abc$)'
>>>?
>>> re.search(s3,'hello,world')
<_sre.SRE_Match object at 0x7f95233047a0>
#第一行的正則串匹配成功
>>> re.search(s3,'aaa,hello,worldabc')
#第二行的匹配失敗
>>> s4 = r'(^hello)|(abc$)'
#s4沒有用單引號加\做跨行,則兩個正則串都匹配上了
>>> re.search(s4,"hello,world")
<_sre.SRE_Match object at 0x182e690>
>>> re.search(s4,"aaa,hello,worldabc")
<_sre.SRE_Match object at 0x7f95233047a0>
>>>?
#注意如何取匹配到的子串(把要抽取的子串對應的正則用圓括號括起來,group從1開始就是圓括號對應的子串)
>>> re.search(r'^(\d+)abc(\d+)$','232abc1').group(0,1,2)
('232abc1', '232', '1')
?
#下面是一個re和lambda混合使用的一個例子
?
#encoding=utf-8
?
import re
?
f = lambda arg: re.search(u'^(\d+)\w+',arg).group(1)
print f(u'1111條評論')
try:
? ? ? ? f(u'aaaa')
except AttributeError,e:
? ? ? ? print str(e)
:!python re_lambda.py
111
'NoneType' object has no attribute 'group'
?
re.findall()很好用的哦?
?
>>> re.findall(r'\\@[A-Za-z0-9]+', s)
['\\@userA', '\\@userB']
>>> s
'hello,world,\\@userA\\@userB'
>>> re.findall(r'\\@([A-Za-z0-9]+)', s)
['userA', 'userB']
?
?
?
20.寫了個爬蟲,之前在做一些url的連接時總是自己來根據各種情況來處理,比如./xxx? #xxxx /xxx神馬的都要考慮,太煩了,后來發現有現成的東西可以用?
?
>>>from urlparse import urljoin
>>>import urllib?
>>>url = urljoin(r"http://book.douban.com/tag/?view=type",u"./網絡小說")
>>> url
u'http://book.douban.com/tag/\u7f51\u7edc\u5c0f\u8bf4'
>>> conn2 = urllib.urlopen(url)? ? ? ? ? ? ? ?
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
? File "/usr/lib64/python2.6/urllib.py", line 86, in urlopen
? ? return opener.open(url)
? File "/usr/lib64/python2.6/urllib.py", line 179, in open
? ? fullurl = unwrap(toBytes(fullurl))
? File "/usr/lib64/python2.6/urllib.py", line 1041, in toBytes
? ? " contains non-ASCII characters")
UnicodeError: URL u'http://book.douban.com/tag/\u7f51\u7edc\u5c0f\u8bf4' contains non-ASCII characters
>>> conn2 = urllib.urlopen(url.encode('utf-8'))
?21.urllib2做http請求時如何添加header,如何獲取cookie的值?
?
?
>>> request = urllib2.Request("http://img1.gtimg.com/finance/pics/hv1/46/178/1031/67086211.jpg",headers={'If-Modified-Since':'Wed, 02 May 2012 18:32:20 GMT'})
#等同于request.add_header('If-Modified-Since','Wed, 02 May 2012 18:32:20 GMT')
>>> urllib2.urlopen(request)
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
? File "/usr/lib64/python2.6/urllib2.py", line 126, in urlopen
? ? return _opener.open(url, data, timeout)
? File "/usr/lib64/python2.6/urllib2.py", line 397, in open
? ? response = meth(req, response)
? File "/usr/lib64/python2.6/urllib2.py", line 510, in http_response
? ? 'http', request, response, code, msg, hdrs)
? File "/usr/lib64/python2.6/urllib2.py", line 435, in error
? ? return self._call_chain(*args)
? File "/usr/lib64/python2.6/urllib2.py", line 369, in _call_chain
? ? result = func(*args)
? File "/usr/lib64/python2.6/urllib2.py", line 518, in http_error_default
? ? raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 304: Not Modified
>>> urllib.urlencode({"aaa":"bbb"})
'aaa=bbb'
>>> urllib.urlencode([("aaa","bbb")])
'aaa=bbb'
#urlencode的使用,在提交post表單時需要把參數k-v用urlencode處理后放入頭部
#urllib2.urlopen(url,data=urllib.urlencode(...))?
今天(13.7.4)遇到一個問題是登錄某個站點時需要把第一次訪問服務器植入的csrftoken作為post數據一起返給服務器,所以就研究了寫怎么獲取cooke的值,具體代碼不便透漏,把棧溢出上的一個例子擺出來(主要看獲取cookie數據的那幾行代碼)?
http://stackoverflow.com/questions/10247054/http-post-and-get-with-cookies-for-authentication-in-python??
?
[dongsong@localhost python_study]$ cat cookie.py?
from urllib2 import Request, build_opener, HTTPCookieProcessor, HTTPHandler
import httplib, urllib, cookielib, Cookie, os
?
conn = httplib.HTTPConnection('webapp.pucrs.br')
?
#COOKIE FINDER
cj = cookielib.CookieJar()
opener = build_opener(HTTPCookieProcessor(cj),HTTPHandler())
req = Request('http://webapp.pucrs.br/consulta/principal.jsp')
f = opener.open(req)
html = f.read()
import pdb
pdb.set_trace()
for cookie in cj:
? ? c = cookie
#FIM COOKIE FINDER
?
params = urllib.urlencode ({'pr1':111049631, 'pr2':'sssssss'})
headers = {"Content-type":"text/html",
? ? ? ? ? ?"Set-Cookie" : "JSESSIONID=70E78D6970373C07A81302C7CF800349"}
? ? ? ? ? ? # I couldn't set the value automaticaly here, the cookie object can't be converted to string, so I change this value on every session to the new cookie's value. Any solutions?
?
conn.request ("POST", "/consulta/servlet/consulta.aluno.ValidaAluno",params, headers) # Validation page
resp = conn.getresponse()
?
temp = conn.request("GET","/consulta/servlet/consulta.aluno.Publicacoes") # desired content page
resp = conn.getresponse()
?
print resp.read()
?
?
?22.如何修改logging的日志輸出文件,尤其在使用multiprocessing模塊做多進程編程時這個問題變得更急迫,因為子進程會繼承父進程的日志輸出文件和格式....?
?
?
def change_log_file(fileName):
? ? h = logging.FileHandler(fileName)
? ? h.setLevel(g_logLevel)
? ? h.setFormatter(logging.Formatter(g_logFormat))
? ??
? ? logger = logging.getLogger()
? ? #print logger.handlers
? ? for handler in logger.handlers:
? ? ? ? handler.close()
? ? while len(logger.handlers) > 0:
? ? ? ? logger.removeHandler(logger.handlers[0])
? ??????
? ? logger.addHandler(h)?
logging設置logger、handler、formatter可以參見django的配置文件,下面是個人寫的一個小例子?
?
[dongsong@localhost python_study]$ cat logging_test.py?
#encoding=utf-8
import logging, sys
?
if __name__ == '__main__':
? ? ? ? logger = logging.getLogger('test')
? ? ? ? logger.setLevel(logging.DEBUG)
? ? ? ? print 'log handlers: %s' % str(logger.manager.loggerDict)
? ? ? ? logger.error('here')
? ? ? ? logger.warning('here')
? ? ? ? logger.info('here')
? ? ? ? logger.debug('here')
?
? ? ? ? #handler = logging.FileHandler('test.log')
? ? ? ? handler = logging.StreamHandler(sys.stdout)
? ? ? ? handler.setLevel(logging.DEBUG)
? ? ? ? formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
? ? ? ? handler.setFormatter(formatter)
? ? ? ? logger.addHandler(handler)
? ? ? ? #logging.getLogger('test').addHandler(logging.NullHandler()) # python 2.7+
? ? ? ? logger.error('here')
? ? ? ? logger.warning('here')
? ? ? ? logger.info('here')
? ? ? ? logger.debug('here')
[dongsong@localhost python_study]$ vpython logging_test.py?
log handlers: {'test': <logging.Logger instance at 0x7f1dde0c2758>}
No handlers could be found for logger "test"
2012-12-26 11:30:48,725 - test - ERROR - here
2012-12-26 11:30:48,725 - test - WARNING - here
2012-12-26 11:30:48,725 - test - INFO - here
2012-12-26 11:30:48,725 - test - DEBUG - here
?
?23.multiprocessing模塊使用demo?
?
?
import multiprocessing
from multiprocessing import Process
import time
?
def func():
? ? ? ? for i in range(3):
? ? ? ? ? ? ? ? print "hello"
? ? ? ? ? ? ? ? time.sleep(1)
?
proc = Process(target = func)
proc.start()
?
while True:
? ? ? ? childList = multiprocessing.active_children()
? ? ? ? print childList
? ? ? ? if len(childList) == 0:
? ? ? ? ? ? ? ? break
? ? ? ? time.sleep(1)
[dongsong@bogon python_study]$ python multiprocessing_children.py?
[<Process(Process-1, started)>]
hello
[<Process(Process-1, started)>]
hello
[<Process(Process-1, started)>]
hello
[<Process(Process-1, started)>]
[]
[dongsong@bogon python_study]$ fg
?
multiprocessing的Pool模塊(進程池)是很好用的,今天差點多此一舉的自己寫了一個(當然,自己寫也是比較easy的,只是必然沒官方的考慮周到)?
?
[dongsong@bogon python_study]$ vpython
Python 2.6.6 (r266:84292, Jun 18 2012, 14:18:47)?
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from multiprocessing import Pool
>>> import time
>>> poolObj = Pool(processes = 10)
>>> procObj = poolObj.apply_async(time.sleep, (20,))
>>> procObj.get(timeout = 1)
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
? File "/usr/lib64/python2.6/multiprocessing/pool.py", line 418, in get
? ? raise TimeoutError
multiprocessing.TimeoutError
>>> print procObj.get(timeout = 21)
None
>>> poolObj.__dict__['_pool']
[<Process(PoolWorker-1, started daemon)>, <Process(PoolWorker-2, started daemon)>, <Process(PoolWorker-3, started daemon)>, <Process(PoolWorker-4, started daemon)>, <Process(PoolWorker-5, started daemon)>, <Process(PoolWorker-6, started daemon)>, <Process(PoolWorker-7, started daemon)>, <Process(PoolWorker-8, started daemon)>, <Process(PoolWorker-9, started daemon)>, <Process(PoolWorker-10, started daemon)>]
>>> poolObj.close()
>>> poolObj.join()?
?
24.關于bs的編碼和str()函數編碼的問題在下面的demo里面可見一斑(跟str()類似的內建函數是unicode())?
?
?
#encoding=utf-8
from bs4 import BeautifulSoup as soup
?
tag = soup((u"<p>白癡代碼</p>"),from_encoding='unicode').body.contents[0]
newStr = str(tag) #tag內部的__str__()返回utf-8編碼的字符串(tag不實現__str__()的話就會按照本文第38條表現了)
print type(newStr),isinstance(newStr,unicode),newStr
try:
? ? ? ? print u"[unicode]hello," + newStr #自動把newStr按照unicode解釋,報錯
except Exception,e:
? ? ? ? print str(e)
print "[utf-8]hello," + newStr
print u"[unicode]hello," + newStr.decode('utf-8')
?
[dongsong@bogon python_study]$ vpython tag_str_test.py?
<type 'str'> False <p>白癡代碼</p>
'ascii' codec can't decode byte 0xe7 in position 3: ordinal not in range(128)
[utf-8]hello,<p>白癡代碼</p>
[unicode]hello,<p>白癡代碼</p>
?25.關于MySQLdb使用的一些問題?
?http://mysql-python.sourceforge.net/
? ? ? 1>
這里是鳥人11年在某個項目中封裝的數據庫操作接口database.py,具體的數據庫操作可以繼承該類并實現跟業務相關的接口
? ? ? 2>cursor.execute(), cursor.fetchall()查出來的是unicode編碼,即使指定connect的charset為utf8
?
? ? ?3>查詢語句需要注意的問題見下述測試代碼;推薦的cursor.execute()用法是cursor.execute(sql, args),因為底層會自動做字符串逃逸?
? ? ? ? ?If you're not familiar with the Python DB-API, notethat the SQL statement incursor.execute() uses placeholders,"%s",rather than adding parameters directly within the SQL. If you use thistechnique, the underlying database library will automatically add quotes andescaping to your parameter(s) as necessary. (Also note that Django expects the"%s" placeholder,not the "?" placeholder, which is used by the SQLitePython bindings. This is for the sake of consistency and sanity.)?
?
? ? ?4>規范的做法需要conn.cursor().execute()后conn.commit(),否則在某些不支持自動提交的數據庫版本上會有問題??
? ? ?5>對于插入操作成功后新增記錄對應的自增主鍵可以用MySQLdb.connections.Connection.insert_id()來獲取(MySQLdb.connections.Connection就是MySQLdb.connect()返回的mysql連接)(2014.5.29)?
?
?
#encoding=utf-8
import MySQLdb
?
conn = MySQLdb.connect(host = "127.0.0.1", port = 3306, user = "xds", passwd = "xds", db = "xds_db", charset = 'utf8')
cursor = conn.cursor()
print cursor
?
siteName = u"百度貼吧"
bbsNames = [u"明星", u"影視"]
?
?
siteName = siteName.encode('utf-8')
for index in range(len(bbsNames)):
? ? ? ? bbsNames[index] = bbsNames[index].encode('utf-8')
?
#正確的用法
#args = tuple([siteName] + bbsNames)
#sql = "select bbs from t_site_bbs where site = %s and bbs in (%s,%s)"
#rts = cursor.execute(sql,args)
#print rts
?
#正確的用法
args = tuple([siteName] + bbsNames)
sql = "select bbs from t_site_bbs where site = '%s' and bbs in ('%s','%s')" % args
print sql
rts = cursor.execute(sql)
print rts
?
#錯誤的用法,報錯
#args = tuple([siteName] + bbsNames)
#sql = "select bbs from t_site_bbs where site = %s and bbs in (%s,%s)" % args
#rts = cursor.execute(sql)
print rts
?
#錯誤的用法,不報錯,但是查不到數據(bbsName的成員是數字串或者英文字符串時正確)
#sql = "select bbs from t_site_bbs where site = '%s' and bbs in %s" % (siteName, str(tuple(bbsNames)))
#print sql
#rts = cursor.execute(sql)
#print rts
?
?
rts = cursor.fetchall()
for rt in rts:
? ? ? ? print rt[0]?
??
對于有自增列的數據表,insert之后可以通過cursor.lastrowid獲取剛插入的記錄的自增id,update不行?
參考:http://stackoverflow.com/questions/706755/how-do-you-safely-and-efficiently-get-the-row-id-after-an-insert-with-mysql-usin??
??
26.關于時間?
?
?
[dongsong@bogon boosencms]$ vpython
Python 2.6.6 (r266:84292, Dec? 7 2011, 20:48:22)?
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.gmtime()
time.struct_time(tm_year=2012, tm_mon=5, tm_mday=18, tm_hour=4, tm_min=14, tm_sec=55, tm_wday=4, tm_yday=139, tm_isdst=0)
>>> time.localtime()
time.struct_time(tm_year=2012, tm_mon=5, tm_mday=18, tm_hour=12, tm_min=15, tm_sec=2, tm_wday=4, tm_yday=139, tm_isdst=0)
>>> time.time()
1337314595.7790151
>>> time.timezone
-28800
>>> time.gmtime(time.time())
time.struct_time(tm_year=2012, tm_mon=5, tm_mday=18, tm_hour=4, tm_min=19, tm_sec=45, tm_wday=4, tm_yday=139, tm_isdst=0)
>>> time.localtime(time.time())
time.struct_time(tm_year=2012, tm_mon=5, tm_mday=18, tm_hour=12, tm_min=19, tm_sec=54, tm_wday=4, tm_yday=139, tm_isdst=0)
>>> time.strftime("%a, %d %b %Y %H:%M:%S +0800", time.localtime(time.time()))
'Fri, 18 May 2012 12:21:20 +0800'
>>> time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(time.time()))? ?
'Fri, 18 May 2012 04:21:36 +0000'
#%Z這玩意到底怎么用的,下面也沒搞明白
>>> time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.gmtime(time.time()))
'Fri, 18 May 2012 04:23:09 CST'
>>> time.strftime("%a, %d %b %Y %H:%M:%S %Z", time.localtime(time.time()))
'Fri, 18 May 2012 12:23:31 CST'
>>> timeStr = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(time.time()))? ? ? ? ?
>>> timeStr
'Fri, 18 May 2012 04:24:29 +0000'
>>> t = time.strptime(timeStr, "%a, %d %b %Y %H:%M:%S %Z")? ? ? ? ? ? ??
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
? File "/usr/lib64/python2.6/_strptime.py", line 454, in _strptime_time
? ? return _strptime(data_string, format)[0]
? File "/usr/lib64/python2.6/_strptime.py", line 325, in _strptime
? ? (data_string, format))
ValueError: time data 'Fri, 18 May 2012 04:24:29 +0000' does not match format '%a, %d %b %Y %H:%M:%S %Z'
>>> t = time.strptime(timeStr, "%a, %d %b %Y %H:%M:%S +0000")
>>> t
time.struct_time(tm_year=2012, tm_mon=5, tm_mday=18, tm_hour=4, tm_min=24, tm_sec=29, tm_wday=4, tm_yday=139, tm_isdst=-1)
#下面是datetime的用法
>>> import datetime
>>> datetime.datetime.today()
datetime.datetime(2012, 5, 18, 12, 28, 25, 892141)
>>> datetime.datetime(2012,12,12,23,54)
datetime.datetime(2012, 12, 12, 23, 54)
>>> datetime.datetime(2012,12,12,23,54,32)
datetime.datetime(2012, 12, 12, 23, 54, 32)
>>> datetime.datetime.fromtimestamp(time.time())
datetime.datetime(2012, 5, 18, 12, 29, 15, 130257)
>>> datetime.datetime.utcfromtimestamp(time.time())
datetime.datetime(2012, 5, 18, 4, 29, 34, 897017)
>>> datetime.datetime.now()
datetime.datetime(2012, 5, 18, 12, 29, 52, 558249)
>>> datetime.datetime.utcnow()
datetime.datetime(2012, 5, 18, 4, 30, 6, 164009)
>>> datetime.datetime.fromtimestamp(time.time()).strftime("%a, %d %b %Y %H:%M:%S")? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
'Fri, 18 May 2012 17:05:30'
>>> datetime.datetime.today().strftime("%a, %d %b %Y %H:%M:%S")? ? ? ? ? ? ? ? ? ? ? ? ??
'Fri, 18 May 2012 17:05:44'
>>> datetime.datetime.strptime('Fri, 18 May 2012 04:24:29', "%a, %d %b %Y %H:%M:%S")? ??
datetime.datetime(2012, 5, 18, 4, 24, 29)
>>> datetime.datetime.fromtimestamp(time.time()).strftime('%X')??
'17:07:14'
>>> datetime.datetime.fromtimestamp(time.time()).strftime('%x')??
'02/28/15'
>>> datetime.datetime.fromtimestamp(time.time()).strftime('%c')??
'Sat Feb 28 17:07:24 2015'
?%a 英文星期簡寫
?%A 英文星期的完全
?%b 英文月份的簡寫
?%B 英文月份的完全
?%c 顯示本地日期時間
?%d 日期,取1-31
?%H 小時, 0-23
?%I 小時, 0-12?
?%m 月, 01 -12
?
%M 分鐘,0-59?
%S 秒,0-61(官網這樣寫的)? %j 年中當天的天數
?%w 顯示今天是星期幾
?%W 第幾周
?%x 當天日期
?%X 本地的當天時間
?%y 年份 00-99間
?%Y 年份的完整拼寫?
?
27.關于整數轉字符串的陷阱?
有些整數是int,有些是long,對于long調用str()處理后返回的字符串是數字+L,該long數字在list等容器中時,對容器調用str()處理時也有這個問題,用者需謹慎啊! 至于一個整數什么時候是int,什么時候是long鳥人正在研究...(當然,指定int或者long就肯定是int或者long了)? 28.join()的用法(列表中的元素必須是字符串)?
?
>>> l = ['a','b','c','d']
>>> '&'.join(l)
'a&b&c&d'
?
29.python的pdb調試?
http://www.ibm.com/developerworks/cn/linux/l-cn-pythondebugger/??
?
跟gdb很類似:?
b line_number 加斷點,還可以指定文件和函數加斷點?
b 180, childWeiboRt.retweetedId == 3508203280986906 條件斷點??
b 顯示所有斷點?
cl breakpoint_number 清除某個斷點?
cl 清除所有斷點?
c 繼續?
n 下一步?
s 跟進函數內部?
bt 調用棧?
whatis obj 查看某變量類型(跟python的內置函數type()等效)?
up 移到調用棧的上一層(frame),可以看該調用點的代碼和變量(當然,程序實際進行到哪里了是不可改變的)?
down 移到調用棧的下一層(frame),可以看該調用點的代碼和變量(當然,程序實際進行到哪里了是不可改變的)?
...??
調試過程中要查看某實例(instanceObj)的屬性值可用下述語句:??
for it in [(attr,getattr(instanceObj,attr)) for attr in dir(instanceObj)]: print it[0],'-->',it[1]?
?
30.在函數內部獲取函數名?
?
>>> import sys
>>> def f2():
...? ? ?print sys._getframe().f_code.co_name
...?
>>> f2()
f2?
?
??
31.url中的空格等特殊字符的處理?
url出現了有+,空格,/,?,%,#,&,=等特殊符號的時候,可能在服務器端無法獲得正確的參數值,如何是好? 解決辦法 將這些字符轉化成服務器可以識別的字符,對應關系如下: URL字符轉義 用其它字符替代吧,或用全角的。 +? ? URL中+號表示空格? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? %2B? ?空格 URL中的空格可以用+號或者編碼? ? ? ? ? ? %20? /? 分隔目錄和子目錄? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? %2F? ? ??? ?分隔實際的URL和參數? ? ? ? ? ? ? ? ? ? ? ? ? ? ? %3F? ? ?%? ?指定特殊字符? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?%25? ? #? ?表示書簽? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?%23? ? ?&? ? URL中指定的參數間的分隔符? ? ? ? ? ? ? ? ? ?%26? ? ? =? ? URL中指定參數的值? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?%3D?
?
>>> import urllib
>>> import urlparse
>>> urlparse.urljoin('http://s.weibo.com/weibo/',urllib.quote('python c++'))?
'http://s.weibo.com/weibo/python%20c%2B%2B'?
??
當url與特殊字符碰撞、然后參數又用于有特殊字符的搜索引擎(lucene等)....?
需要把url轉義再轉義,否則特殊字符安全通過http協議后就裸體進入搜索引擎了,查到的將不是你要的東東...?
參考:http://stackoverflow.com/questions/688766/getting-401-on-twitter-oauth-post-requests?
通過觀察url可以發現http://s.weibo.com瀏覽器腳本也是做了這種處理的??
[dongsong@bogon python_study]$ cat url.py?
#encoding=utf-8
?
import urllib, urlparse
?
if __name__ == '__main__':
? ? ? ? baseUrl = 'http://s.weibo.com/weibo/'
? ? ? ? url = urlparse.urljoin(baseUrl, urllib.quote(urllib.quote('python c++')))
? ? ? ? print url
? ? ? ? conn = urllib.urlopen(url)
? ? ? ? data = conn.read()
? ? ? ? f = file('/tmp/d.html', 'w')
? ? ? ? f.write(data)
? ? ? ? f.close()
[dongsong@bogon python_study]$ vpython url.py?
http://s.weibo.com/weibo/python%2520c%252B%252B?
??
32.json模塊編碼問題?
json.dumps()默認行為:?
? ? ? ? 把數據結構中所有字符串轉換成unicode編碼,然后對unicode串做編碼轉義(\u56fd變成\\u56fd)再整個導出utf-8編碼(由參數encoding的默認值utf-8控制,沒必要動它)的json串?
? ? ? ? 如原數據結構中的元素編碼不一致不影響dumps函數的行為,因為導出json串之前會把所有元素串轉換成unicode串??
參數ensure_ascii默認是True,如設置為False會改變dumps的行為:?
? ? ? ? 原數據結構中的字符串編碼為unicode則導出的json串是unicode串,且內部unicode串不做轉義(\u56fd還是\u56fd);?
? ? ? ? 原數據結構中的字符串編碼為utf-8則導出的json串是utf-8串,且內部utf-8串不做轉義(\xe5\x9b\xbd還是\xe5\x9b\xbd);?
? ? ? ? 如原數據結構中的元素編碼不一致則dumps函數會出現錯誤?
? ? ? ? 通過這種方式拿到的json串是可以做編碼轉換的,默認行為得到的json串不行(因為原數據結構的字符串元素被轉義了,對json串整個做編碼轉換無法觸動原數據結構的字符串元素)?
? ? ? ? warning--->2012-07-11 10:00:?
? ? ? ? ? ? ? ? ? 今天遇到一個問題,用這種方式轉一個帶繁體字的字典,轉換成功,只是把json串入庫時報錯?
? ? ? ? ? ? ? ? ? _mysql_exceptions.Warning: Incorrect string value: '\xF0\x9F\x91\x91\xE7\xAC...' for column 'detail' at row 1?
? ? ? ? ? ? ? ? ? 而用第一種方式存庫就沒有問題,初步認定是json.dumps(ensure_ascii = False)對繁體字的處理有編碼問題?
對于一些編碼比較雜亂的數據,可能json.loads()會拋UnicodeDecodeError異常(比如我今天(2013.3.19)遇到的qq開放平臺API返回的utf8編碼json串在反解時總遇到這個問題),可如下解決:?
? ? ? ? myString = jsonStr.decode('utf-8', 'ignore') #轉成unicode,并忽略錯誤?
? ? ? ? ?jsonObj = json.loads(myString)?
? ? ? ? 可能會丟數據,但總比什么也不干要強。??
?
#encoding=utf-8
?
import json
from pprint import pprint
?
def show_rt(rt):
? ? ? ? pprint(rt)
? ? ? ? print rt
? ? ? ? print "type(rt) is %s" % type(rt)
?
if __name__ == '__main__':
? ? ? ? unDic = {
? ? ? ? ? ? ? ? ? ? ? ? u'中國':u'北京',
? ? ? ? ? ? ? ? ? ? ? ? u'日本':u'東京',
? ? ? ? ? ? ? ? ? ? ? ? u'法國':u'巴黎'
? ? ? ? ? ? ? ? }
? ? ? ? utf8Dic = {
? ? ? ? ? ? ? ? ? ? ? ? r'中國':r'北京',
? ? ? ? ? ? ? ? ? ? ? ? r'日本':r'東京',
? ? ? ? ? ? ? ? ? ? ? ? r'法國':r'巴黎'
? ? ? ? ? ? ? ? }
?
? ? ? ? pprint(unDic)
? ? ? ? pprint(utf8Dic)
?
? ? ? ? print "\nunicode instance dumps to string:"
? ? ? ? rt = json.dumps(unDic)
? ? ? ? show_rt(rt)
? ? ? ? print "utf-8 instance dumps to string:"
? ? ? ? rt = json.dumps(utf8Dic)
? ? ? ? show_rt(rt)
?
? ? ? ? #encoding is the character encoding for str instances, default is UTF-8
? ? ? ? #If ensure_ascii is False, then the return value will be a unicode instance, default is True
? ? ? ? print "\nunicode instance dumps(ensure_ascii=False) to string:"
? ? ? ? rt = json.dumps(unDic,ensure_ascii=False)
? ? ? ? show_rt(rt)
? ? ? ? print "utf-8 instance dumps(ensure_ascii=False) to string:"
? ? ? ? rt = json.dumps(utf8Dic,ensure_ascii=False)
? ? ? ? show_rt(rt)
?
? ? ? ? print "\n-----------------數據結構混雜編碼-----------------"
? ? ? ? unDic[u'日本'] = r'東京'
? ? ? ? utf8Dic[r'日本'] = u'東京'
? ? ? ? pprint(unDic)
? ? ? ? pprint(utf8Dic)
?
? ? ? ? print "\nunicode instance dumps to string:"
? ? ? ? try:
? ? ? ? ? ? ? ? rt = json.dumps(unDic)
? ? ? ? except Exception,e:
? ? ? ? ? ? ? ? print "%s:%s" % (type(e),str(e))
? ? ? ? else:
? ? ? ? ? ? ? ? show_rt(rt)
? ? ? ? print "utf-8 instance dumps to string:"
? ? ? ? try:
? ? ? ? ? ? ? ? rt = json.dumps(utf8Dic)
? ? ? ? except Exception,e:
? ? ? ? ? ? ? ? print "%s:%s" % (type(e),str(e))
? ? ? ? else:
? ? ? ? ? ? ? ? show_rt(rt)
?
? ? ? ? print "\nunicode instance dumps(ensure_ascii=False) to string:"
? ? ? ? try:
? ? ? ? ? ? ? ? rt = json.dumps(unDic, ensure_ascii=False)
? ? ? ? except Exception,e:
? ? ? ? ? ? ? ? print "%s:%s" % (type(e),str(e))
? ? ? ? else:
? ? ? ? ? ? ? ? show_rt(rt)
? ? ? ? print "utf-8 instance dumps to string:"
? ? ? ? try:
? ? ? ? ? ? ? ? rt = json.dumps(utf8Dic, ensure_ascii=False)
? ? ? ? except Exception,e:
? ? ? ? ? ? ? ? print "%s:%s" % (type(e),str(e))
? ? ? ? else:
? ? ? ? ? ? ? ? show_rt(rt)
[dongsong@bogon python_study]$ vpython json_test.py?
{u'\u4e2d\u56fd': u'\u5317\u4eac',
?u'\u65e5\u672c': u'\u4e1c\u4eac',
?u'\u6cd5\u56fd': u'\u5df4\u9ece'}
{'\xe4\xb8\xad\xe5\x9b\xbd': '\xe5\x8c\x97\xe4\xba\xac',
?'\xe6\x97\xa5\xe6\x9c\xac': '\xe4\xb8\x9c\xe4\xba\xac',
?'\xe6\xb3\x95\xe5\x9b\xbd': '\xe5\xb7\xb4\xe9\xbb\x8e'}
?
unicode instance dumps to string:
'{"\\u4e2d\\u56fd": "\\u5317\\u4eac", "\\u65e5\\u672c": "\\u4e1c\\u4eac", "\\u6cd5\\u56fd": "\\u5df4\\u9ece"}'
{"\u4e2d\u56fd": "\u5317\u4eac", "\u65e5\u672c": "\u4e1c\u4eac", "\u6cd5\u56fd": "\u5df4\u9ece"}
type(rt) is <type 'str'>
utf-8 instance dumps to string:
'{"\\u4e2d\\u56fd": "\\u5317\\u4eac", "\\u6cd5\\u56fd": "\\u5df4\\u9ece", "\\u65e5\\u672c": "\\u4e1c\\u4eac"}'
{"\u4e2d\u56fd": "\u5317\u4eac", "\u6cd5\u56fd": "\u5df4\u9ece", "\u65e5\u672c": "\u4e1c\u4eac"}
type(rt) is <type 'str'>
?
unicode instance dumps(ensure_ascii=False) to string:
u'{"\u4e2d\u56fd": "\u5317\u4eac", "\u65e5\u672c": "\u4e1c\u4eac", "\u6cd5\u56fd": "\u5df4\u9ece"}'
{"中國": "北京", "日本": "東京", "法國": "巴黎"}
type(rt) is <type 'unicode'>
utf-8 instance dumps(ensure_ascii=False) to string:
'{"\xe4\xb8\xad\xe5\x9b\xbd": "\xe5\x8c\x97\xe4\xba\xac", "\xe6\xb3\x95\xe5\x9b\xbd": "\xe5\xb7\xb4\xe9\xbb\x8e", "\xe6\x97\xa5\xe6\x9c\xac": "\xe4\xb8\x9c\xe4\xba\xac"}'
{"中國": "北京", "法國": "巴黎", "日本": "東京"}
type(rt) is <type 'str'>
?
-----------------數據結構混雜編碼-----------------
{u'\u4e2d\u56fd': u'\u5317\u4eac',
?u'\u65e5\u672c': '\xe4\xb8\x9c\xe4\xba\xac',
?u'\u6cd5\u56fd': u'\u5df4\u9ece'}
{'\xe4\xb8\xad\xe5\x9b\xbd': '\xe5\x8c\x97\xe4\xba\xac',
?'\xe6\x97\xa5\xe6\x9c\xac': u'\u4e1c\u4eac',
?'\xe6\xb3\x95\xe5\x9b\xbd': '\xe5\xb7\xb4\xe9\xbb\x8e'}
?
unicode instance dumps to string:
'{"\\u4e2d\\u56fd": "\\u5317\\u4eac", "\\u65e5\\u672c": "\\u4e1c\\u4eac", "\\u6cd5\\u56fd": "\\u5df4\\u9ece"}'
{"\u4e2d\u56fd": "\u5317\u4eac", "\u65e5\u672c": "\u4e1c\u4eac", "\u6cd5\u56fd": "\u5df4\u9ece"}
type(rt) is <type 'str'>
utf-8 instance dumps to string:
'{"\\u4e2d\\u56fd": "\\u5317\\u4eac", "\\u6cd5\\u56fd": "\\u5df4\\u9ece", "\\u65e5\\u672c": "\\u4e1c\\u4eac"}'
{"\u4e2d\u56fd": "\u5317\u4eac", "\u6cd5\u56fd": "\u5df4\u9ece", "\u65e5\u672c": "\u4e1c\u4eac"}
type(rt) is <type 'str'>
?
unicode instance dumps(ensure_ascii=False) to string:
<type 'exceptions.UnicodeDecodeError'>:'ascii' codec can't decode byte 0xe4 in position 1: ordinal not in range(128)
utf-8 instance dumps to string:
<type 'exceptions.UnicodeDecodeError'>:'ascii' codec can't decode byte 0xe4 in position 1: ordinal not in range(128)
?
33.json序列化字典會把數字key變成字符串?
?
>>> import json
>>> d = {1:[1,2,3,4],0:()}
>>> d
{0: (), 1: [1, 2, 3, 4]}
>>> s = json.dumps(d)
>>> s
'{"0": [], "1": [1, 2, 3, 4]}'
>>> json.loads(s)
{u'1': [1, 2, 3, 4], u'0': []}
?官網說明:?
?
?Keys in key/value pairs of JSON are always of the type? str. Whena dictionary is converted into JSON, all the keys of the dictionary arecoerced to strings. As a result of this, if a dictionary is converedinto JSON and then back into a dictionary, the dictionary may not equalthe original one. That is,? loads(dumps(x)) !=? x if x has non-stringkeys.?
? ?
?
34.交互模式下_表示上次最后一次運算的結果?
??
35.多進程模塊的比較?
? ? os.popen()和popen2.*都不是官方倡導的用法,subprocess才是?
? ? os.popen()啟動子進程時命令后面如果不加地址符就會把父進程阻塞住;該命令使用非常方便,但是它僅僅返回一個跟子進程通信的pipe(默認的mode是讀,讀的是子進程的stdout和stderr)而已,沒辦法直接殺掉子進程或者獲取子進程的信息(可以從pipe寫信息通知子進程讓子進程自行終止,但是這個很扯淡,你懂的);對pipe的fd調用close()可以得到子進程的退出碼(我沒用過,^_^);在前幾個項目里面我頻繁使用該命令,因為當時的環境對進程的控制比較粗線條??
? ? popen2.*這個模塊還沒用過,不過顧名思義popen2.popen2()就是啟動子進程時返回stdin和stdout,popen2.popen3()就是啟動子進程時返回stdout,stdin,stderr....跟os.popen好像也沒多大改進?
? ? multiprocessing是仿多線程threading接口的多進程模塊,需要注意文件描述符、數據庫連接共享的問題;這個和其他執行命令行命令啟動子進程的多進程模塊是不一樣滴?
? ? subprocess注意僵尸進程的產生,系統一般會為已退出的子進程保留一個進程退出碼等信息的結構、供父進程使用,當父進程wait()子進程時系統知道父進程已不需要該結構則會釋放,如果父進程不wait而直接退出那么該子進程(已退出,等待wait)就會變成僵尸,占用系統進程號??
? ? subprocess的用法:?
?
>>> obj2 = subprocess.Popen('python /home/dongsong/python_study/child2.py', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> dir(obj2)
['__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_timeout', '_child_created', '_close_fds', '_communicate', '_communicate_with_poll', '_communicate_with_select', '_communication_started', '_execute_child', '_get_handles', '_handle_exitstatus', '_input', '_internal_poll', '_remaining_time', '_set_cloexec_flag', '_translate_newlines', 'communicate', 'kill', 'pid', 'poll', 'returncode', 'send_signal', 'stderr', 'stdin', 'stdout', 'terminate', 'universal_newlines', 'wait']
>>> dir(obj2.stdout)
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']
>>> obj2.stdout.read()
'[<logging.StreamHandler instance at 0x7fdb0ad63248>]\naaaaa\naaaaa\naaaaa\naaaaa\naaaaa\naaaaa\naaaaa\naaaaa\naaaaa\naaaaa\n'
>>> obj2.stdout.read()
''
>>> obj2.communicate()[0]
''
>>> obj2.communicate()[1]
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
? File "/usr/lib64/python2.6/subprocess.py", line 729, in communicate
? ? stdout, stderr = self._communicate(input, endtime)
? File "/usr/lib64/python2.6/subprocess.py", line 1310, in _communicate
? ? stdout, stderr = self._communicate_with_poll(input, endtime)
? File "/usr/lib64/python2.6/subprocess.py", line 1364, in _communicate_with_poll
? ? register_and_append(self.stdout, select_POLLIN_POLLPRI)
? File "/usr/lib64/python2.6/subprocess.py", line 1343, in register_and_append
? ? poller.register(file_obj.fileno(), eventmask)
ValueError: I/O operation on closed file
>>> obj2.stderr.read()? ?
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file
>>> args = shlex.split('python /home/dongsong/python_study/child2.py')
>>> obj = subprocess.Popen(args)
?36.設置文件對象非阻塞讀取?
?
?
flags = fcntl.fcntl(procObj.stdout.fileno(), fcntl.F_GETFL)
fcntl.fcntl(procObj.stdout.fileno(), fcntl.F_SETFL, flags|os.O_NONBLOCK)
?
?
37.如何創建deamon進程(可避免僵尸進程)?
原理在僵尸的百科里有提到:fork兩次,父進程fork一個子進程,然后繼續工作,子進程fork一 個孫進程后退出,那么孫進程被init接管,孫進程結束后,init會回收。不過子進程的回收 還要自己做。?
可以參考這人的實現,這個只能用于純粹的學習,沒什么實際意義http://blog.csdn.net/snleo/article/details/4410305?
??
38.默認編碼和內建函數str()的問題?
str(xx)把xx轉換成系統默認編碼(sys.getdefaultencoding())的適合打印的字符串,一般默認是ascii,那么xx如果是unicode漢字就會報錯;默認編碼改成utf-8當然就不會報錯了?
建議不要修改系統默認編碼,會影響一些庫的使用;一定要改可用這些方法。其中sys.setdefaultencoding()方法不是任何場景都有效(Thesetdefaultencoding is used in python-installed-dir/site-packages/pyanaconda/sitecustomize.py)?
?
[dongsong@bogon python_study]$ vpython
Python 2.6.6 (r266:84292, Dec? 7 2011, 20:48:22)?
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'ascii'
>>> s = u'中國'
>>> str(s)
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
>>> s.encode('utf-8')
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> sys.setdefaultencoding('utf-8')
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'setdefaultencoding'
>>> d = {u'中國':u'北京'}
>>> d
{u'\u4e2d\u56fd': u'\u5317\u4eac'}
>>> str(d)
"{u'\\u4e2d\\u56fd': u'\\u5317\\u4eac'}"
#修改默認編碼
[dongsong@bogon python_study]$ cat ~/venv/lib/python2.6/site-packages/sitecustomize.py
import sys
sys.setdefaultencoding('utf-8')
[dongsong@bogon python_study]$ vpython -c 'import sys; print sys.getdefaultencoding();'
utf-8
[dongsong@bogon python_study]$ vpython
Python 2.6.6 (r266:84292, Dec? 7 2011, 20:48:22)?
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = u'中國'?
>>> str(s)
'\xe4\xb8\xad\xe5\x9b\xbd'
>>> import sys
>>> print sys.getdefaultencoding()
utf-8
>>> d = {u'中國':u'北京'}
>>> d
{u'\u4e2d\u56fd': u'\u5317\u4eac'}
>>> str(d)
"{u'\\u4e2d\\u56fd': u'\\u5317\\u4eac'}"?
可以用python -S 跳過site.py(site.py這個東東可以看看python源碼里面的內容),然后sys模塊就直接支持setdefaultencoding()方法了。?
39.trackback?
?
...
except Exception,e:
? ? ? ? ? ? ? ? if not isinstance(e, APIError):
? ? ? ? ? ? ? ? ? ? traceback.print_exc(file=sys.stderr)?
或者?
?
import sys
? ? tp,val,td = sys.exc_info()
?sys.exc_info()的返回值是一個tuple, (type, value/message, traceback)
?這里的type ---- 異常的類型
?value/message ---- 異常的信息或者參數
?
traceback ---- 包含調用棧信息的對象。?
可用traceback模塊處理traceback對象,traceback.print_tb()打印traceback對象,traceback.format_tb()返回traceback對象的可打印串??
?
參考:http://hi.baidu.com/whaway/item/8136af0b404dd1813c42e207?
?
40.用python做GUI開發的一些選擇 GUI Programming in Python( http://wiki.python.org/moin/GuiProgramming)?
cocos2d :Cocos2D家族的前世今生??
? ? ? ? ? ? ? ? ? ? ?cocos2d官網?
? ? ? ? ? ? ? ? ? ? ?cocos2d-x?
pygame:pygame維基? ?
?
? ? ? ? ? ? ? ? ? ?pygame官網?
tkinter:tkinter教程?
? ? ? ? ? ? ? ? tkinter官網?
wxpython:wxpython官網?
??
圖像處理和圖表見另一篇文章http://blog.csdn.net/xiarendeniao/article/details/7991305??
??
41.類的靜態方法和類方法(用內建函數staticmethod()和classmethod()修飾的類的成員方法)?
在python中,靜態方法和類方法都是可以通過類對象和類對象實例訪問。但是區別是:??
? ? ? 1>@classmethod修飾的類的方法是類方法,第一個參數cls是接收類變量。有子類繼承時,調用該類方法時,傳入的類變量cls是子類,而非父類。不同于C++中類的靜態方法。調用方法:ClassA.func() or ClassA().func()(后者調用時函數忽略類的實例)classmethod() is useful for creating alternateclass constructors.??
?
>>> class A:
...? ? ?@classmethod
...? ? ?def func(cls):
...? ? ? ? ? ? ?import pdb
...? ? ? ? ? ? ?pdb.set_trace()
...? ? ? ? ? ? ?pass
...?
>>> A.func()
> <stdin>(6)func()
(Pdb) cls
<class __main__.A at 0x7fc8b056ea70>
(Pdb) type(cls)
<type 'classobj'>
(Pdb)?
>>> type(A())
<type 'instance'>
?
? ? ? 2>@staticmethod修飾的類的方法是靜態方法,靜態方法不接收隱式的第一個參數。基本上跟一個全局函數相同,跟C++中類的靜態方法很類似。調用方法:ClassA.func() or ClassA().func() (后者調用時函數忽略類的實例)??
?
? ? ? 3>沒有上述修飾的類的方法是普通方法(實例方法),第一個參數是self,接收類的實例。調用方法:ClassA().func()?
??
42.字典合并?
?
>>> d1
{1: 6, 11: 12, 12: 13, 13: 14}
>>> d2
{1: 2, 2: 3, 3: 4}
>>> dict(d2, **d1)
{1: 6, 2: 3, 3: 4, 11: 12, 12: 13, 13: 14}
>>> dict(d1,**d2)?
{1: 2, 2: 3, 3: 4, 11: 12, 12: 13, 13: 14}
>>> d = dict(d1)
>>> d
{1: 6, 11: 12, 12: 13, 13: 14}
>>> d2
{1: 2, 2: 3, 3: 4}
>>> d.update(d2)
>>> d
{1: 2, 2: 3, 3: 4, 11: 12, 12: 13, 13: 14}
>>> d = dict(d2)
>>> d
{1: 2, 2: 3, 3: 4}
>>> d1
{1: 6, 11: 12, 12: 13, 13: 14}
>>> d.update(d1)
>>> d
{1: 6, 2: 3, 3: 4, 11: 12, 12: 13, 13: 14}
?
43.網絡超時處理?
1>>urllib2.urlopen(url,timeout=xx)?
2>>socket.setdefaulttimeout(xx) #(全局socket超時設置)?
3>>定時器?
?
from urllib2 import urlopen
from threading import Timer
url = "http://www.python.org"
def handler(fh):
? ? ? ? fh.close()
fh = urlopen(url)
t = Timer(20.0, handler,[fh])
t.start()
data = fh.read()
t.cancel()
?
44.excel處理?
以前一直用的csv模塊,讀寫csv格式文件,然后用excel軟件打開另存為xls文件?
今天(2012.10.30)發現這個庫更直接,更強大http://www.python-excel.org/??
鳥人用的版本:(xlwt-0.7.4 xlrd-0.8.0 xlutils-1.5.2)??
設置行的高度可以用sheetObj.row(index).set_style(easyxf('font:height 720;'))? 設置列的寬度可以用sheetObj.col(index).width = 1000 其他那些方法差不多都有bug 設置不上http://reliablybroken.com/b/2011/10/widths-heights-with-xlwt-python/?
?
#encoding=utf-8
from xlwt import Workbook, easyxf
?
book = Workbook(encoding='utf-8')
sheet1 = book.add_sheet('Sheet 1')
sheet1.col_width(20000)
book.add_sheet('Sheet 2')
sheet1.write(0,0,'起點')
sheet1.write(0,1,'B1')
row1 = sheet1.row(1)
row1.write(0,'Ai2')
row1.write(1,'B2')
sheet1.col(0).width = 10000
sheet1.col(1).width = 20000
#sheet1.default_col_width = 20000 #bug invalid
#sheet1.col_width(30000) #bug invalid
#sheet1.default_row_height = 5000 #bug invalid
#sheet1.row(0).height = 5000 #bug invalid
sheet1.row(0).set_style(easyxf('font:height 400;'))
style = easyxf('pattern: pattern solid, fore_colour red;'
? ? ? ? ? ? ? ? 'align: vertical center, horizontal center;'
? ? ? ? ? ? ? ? 'font: bold true;')
sheet1.write_merge(2,5,2,5,'Merged',style)
sheet2 = book.get_sheet(1)
sheet2.row(0).write(0,'Sheet 2 A1')
sheet2.row(0).write(1,'Sheet 2 B1')
sheet2.flush_row_data()
sheet2.write(1,0,'Sheet 2 A3')
sheet2.col(0).width = 5000
sheet2.col(0).hidden = True
book.save('simple.xls')?
用這個庫的時候很頭疼的一點是不知道設置的寬度/高度/顏色在視覺上到底是什么樣子,鳥人寫了個腳本把所有支持的顏色和常用的寬高打印出來已備選,具體參見http://blog.csdn.net/xiarendeniao/article/details/8276957??
??
45.在本機有多個ip地址的情況下,urllib2發起http請求時如何指定使用哪個IP地址?兩種方式,方便且稍帶取巧性質的是篡改socket模塊的socket方法(下面的代碼是這種),另一種是:A better way is to extendconnect() method in subclass ofHTTPConnection and redefinehttp_open() method in subclass ofHTTPHandler?
?
def bind_alt_socket(alt_ip):
? ? true_socket = socket.socket
? ? def bound_socket(*a, **k):
? ? ? ? sock = true_socket(*a, **k)
? ? ? ? sock.bind((alt_ip, 0))
? ? ? ? return sock
? ? socket.socket = bound_socket參考:
http://www.rossbates.com/2009/10/urllib2-with-multiple-network-interfaces/?
?
? ? ? ? ? ? http://stackoverflow.com/questions/1150332/source-interface-with-python-and-urllib2??
??
46.PyQt4的安裝:?
?
1.sip安裝
wget http://sourceforge.net/projects/pyqt/files/sip/sip-4.14.1/sip-4.14.1.tar.gz
vpython configure.py
make
sudo make install
?
2.sudo yum install qt qt-devel -y
? sudo yum install qtwebkit qtwebkit-devel -y //沒有這一個操作的話,下面configure操作就會不生成QtWebKit的Makefile
?
3.pyqt安裝
wget http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.9.5/PyQt-x11-gpl-4.9.5.tar.gz
vpython configure.py -q/usr/bin/qmake-qt4 -g
make?
make installdir(PyQt4)看不到的模塊不表示不存在啊親!so動態庫可以用from PyQt4 import QtGui或者import PyQt4.QtGui來引入的啊親!尼瑪,我一直以為安裝失敗了,各種嘗試各種找原因啊,崩潰中...
?
?
47.一個python解釋器要使用另一個python解釋器的環境(安裝的模塊)?
參考:http://mydjangoblog.com/2009/03/30/django-mod_python-and-virtualenv/https://pypi.python.org/pypi/virtualenv?
下述示例是在默認python環境中使用virtualenv python中安裝的callme模塊:?
?
[dongsong@localhost ~]$ python
Python 2.6.6 (r266:84292, Jun 18 2012, 14:18:47)?
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import callme
Traceback (most recent call last):
? File "<stdin>", line 1, in <module>
ImportError: No module named callme
>>> activate_this = '/home/dongsong/venv/bin/activate_this.py'? ? ? ? ? ??
>>> execfile(activate_this, dict(__file__=activate_this))
>>> import callme
>>> 至于如何使得mod_python使用virtualenv python環境,可參考前述連接:?
?
?
#myvirtualdjango.py
?
activate_this = '/home/django/progopedia.ru/ve/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
?
from django.core.handlers.modpython import handler
?
<VirtualHost 127.0.0.1:81>
? ? ServerName progopedia.ru
? ? ServerAdmin admin@progopedia.ru
?
? ? <Location "/">
? ? ? ? SetHandler python-program
? ? ? ? PythonPath "['/home/django/progopedia.ru/ve/bin', '/home/django/progopedia.ru/src/progopedia_ru_project/'] + sys.path"
? ? ? ? PythonHandler myvirtualdjango
? ? ? ? SetEnv DJANGO_SETTINGS_MODULE settings
? ? ? ? SetEnv PYTHON_EGG_CACHE /var/tmp/egg
? ? ? ? PythonInterpreter polyprog_ru
? ? </Location>
</VirtualHost>
?
48.格式化輸出?
%r是一個萬能的格式付,它會將后面給的參數原樣打印出來,帶有類型信息??
print 會自動在行末加上回車,如果不需回車,只需在print語句的結尾添加一個逗號”,“,就可以改變它的行為?
更多精彩用法請見http://www.pythonclub.org/python-basic/print??
%r是用對象的repr形式,%s是用str形式??
?
49.finally 很容易搞錯哦!?
?
[dongsong@localhost python_study]$ cat finally_test.py?
#encoding=utf-8
?
def func():
? ? ? ? a = 1
? ? ? ? try:
? ? ? ? ? ? ? ? return a
? ? ? ? except Exception,e:
? ? ? ? ? ? ? ? print '%r' % e
? ? ? ? else:
? ? ? ? ? ? ? ? print 'no exception'
? ? ? ? finally:
? ? ? ? ? ? ? ? print 'finally'
? ? ? ? ? ? ? ? a += 1
?
a = func()
print 'func returned %s' % a
[dongsong@localhost python_study]$ vpython finally_test.py?
finally
func returned 1
?
50.stackless?
官網:http://www.stackless.com/??
中文資料(有例子哦~):http://gashero.yeax.com/?p=30??
1>當調用 stackless.schedule() 的時候,當前活動微進程將暫停執行,并將自身重新插入到調度器隊列的末尾,好讓下一個微進程被執行。 一旦在它前面的所有其他微進程都運行過了,它將從上次 停止的地方繼續開始運行。這個過程會持續,直到所有的活動微進程都完成了運行過程。這就是使用stackless達到合作式多任務的方式。 2>接收的微進程調用 channel.receive() 的時候,便阻塞住,這意味著該微進程暫停執行,直到有信息從這個通道送過來。除了往這個通道發送信息以外,沒有其他任何方式可以讓這個微進程恢復運行。 若有其他微進程向這個通道發送了信息,則不管當前的調度到了哪里,這個接收的微進程都立即恢復執行;而發送信息的微進程則被轉移到調度列表的末尾,就像調用了 stackless.schedule() 一樣。 同樣注意,發送信息的時候,若當時沒有微進程正在這個通道上接收,也會使當前微進程阻塞。 發送信息的微進程,只有在成功地將數據發送到了另一個微進程之后,才會重新被插入到調度器中。 3>清除堆棧溢出的問題:是否還記得,先前我提到過,那個代碼的遞歸版本,有經驗的程序員會一眼看出毛病。但老實說,這里面并沒有什么“計算機科學”方面的原因在阻礙它的正常工作,有些讓人堅信的東西,其實只是個與實現細節有關的小問題——只因為大多數傳統編程語言都使用堆棧。某種意義上說,有經驗的程序員都是被洗了腦,從而相信這是個可以接受的問題。而stackless,則真正察覺了這個問題,并除掉了它。 4>微線程--輕量級線程:與當今的操作系統中內建的、和標準Python代碼中所支持的普通線程相比,“微線程”要更為輕量級,正如其名稱所暗示。它比傳統線程占用更少的內存,并且微線程之間的切換,要比傳統線程之間的切換更加節省資源。 5>計時:現在,我們對若干次實驗運行過程進行計時。Python標準庫中有一個 timeit.py 程序,可以用作此目的。 6>我們將channel的preference 設置為1,這使得調用send之后任務不被阻塞而繼續運行,以便在之后輸出正確的倉庫信息。 7>In stackless, the balance of a channel is how many tasklets are waiting to send or receive on it.正數表示有send的個數;負數表示receive的個數;0表示沒有等待。?
總結:stackless python還是受限于GIL,多核用不上,只是比python的傳統thread有些改進而已(http://stackoverflow.com/questions/377254/stackless-python-and-multicores)。所以multiprocessing構建多進程、進程內部用stackless構建微線程是不錯的搭配。EVE服務器端使用stackless做的(貌似是C++/stackless python),好想看看他們的代碼啊,哈哈哈。??
stackless python安裝:參考http://opensource.hyves.org/concurrence/install.html#installing-stackless?
?
?
sudo yum install readline-devel -y
./configure --prefix=/opt/stackless --with-readline --with-zlib=/usr/include
make
make install
?51.動態加載模塊?
?
內建函數__import__()?
[dongsong@localhost python_study]$ touch mds/__init__.py
[dongsong@localhost python_study]$ vpython
Python 2.6.6 (r266:84292, Jun 18 2012, 14:18:47)?
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> m = __import__('mds.m1', globals(), locals(), fromlist=[], level = 0)
>>> m
<module 'mds' from 'mds/__init__.py'>?
第一次在自己的代碼中實用這個函數(2014.6.25),發現需要注意的問題挺多的,要仔細閱讀官方說明?
?
class RobotMeta(type):
? ? def __new__(cls, name, bases, attrs):
? ? ? ? newbases = list(bases)
? ? ? ? import testcase
? ? ? ? import pkgutil
? ? ? ? for importer, modname, ispkg in pkgutil.iter_modules(testcase.__path__):
? ? ? ? ? ? if ispkg: continue
? ? ? ? ? ? mod = __import__('testcase.'+modname, globals(), locals(), fromlist=(modname,), level=1)
? ? ? ? ? ? if hasattr(mod, 'Robot'):
? ? ? ? ? ? ? ? newbases.append(mod.Robot)
? ? ? ? return super(RobotMeta, cls).__new__(cls, name, tuple(newbases), attrs)importlib庫,
importlib.import_module()?
?
[dongsong@localhost python_study]$ touch mds/__init__.py
[dongsong@localhost python_study]$ vpython
Python 2.6.6 (r266:84292, Jun 18 2012, 14:18:47)?
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import importlib
>>> m = importlib.import_module('mds.m1')
>>> m
<module 'mds.m1' from 'mds/m1.py'>
>>>?
?
52.對于user-defined class,如何使其支持pickle和cPickle?(下面是對項目中一個繼承自dict的json串反解對象所做的修改,參考http://stackoverflow.com/questions/5247250/why-does-pickle-getstate-accept-as-a-return-value-the-very-instance-it-requi)?
def __getstate__(self):?
? ? ? ? return dict(self)
? ??
def __setstate__(self, state):
? ? ? ? return self.update(state)
?
53.判斷字符串的組成?
s.isalnum()? 所有字符都是數字或者字母 s.isalpha()? 所有字符都是字母 s.isdigit()? 所有字符都是數字 s.islower()? 所有字符都是小寫 s.isupper()? 所有字符都是大寫 s.istitle()? 所有單詞都是首字母大寫,像標題 s.isspace()? 所有字符都是空白字符、\t、\n、\r?
??
54.python networking framework, 這種python并發問題三言兩語難盡其意,故另起爐灶見http://blog.csdn.net/xiarendeniao/article/details/9143059??
Twisted是比較常見和廣泛使用的(module index)?
concurrence 跟stackless有一腿(stackless和libevent的結合體),所以對我比較有吸引力?
cogen 跟上面的那個相似,移植性更好一些?
gevent greenlet和libevent的結合體(greenlet是stackless的副產品、只是比stackless更原始一些、更容易滿足coder對協程的控制欲),這樣看跟concurrence原理差不多哦?
得出上述總結的原材料:http://stackoverflow.com/questions/1824418/a-clean-lightweight-alternative-to-pythons-twisted?
?
55.python環境變量(environment variables)?
?
import os
if not os.environ.has_key('DJANGO_SETTINGS_MODULE'):
? ? os.environ['DJANGO_SETTINGS_MODULE'] = 'boosencms.settings'
else:
? ? print 'DJANGO_SETTINGS_MODULE: %s' % os.environ['DJANGO_SETTINGS_MODULE']?
56.yield,用于生成generator的語法,generator是一個可迭代一次的對象,用generator做迭代(遍歷)相對于list、tuple等結構的優勢是沒必要所有數據都在內存中,詳解見官網文檔和棧溢出討論帖??
?
[dongsong@localhost python-study]$ !cat
cat yield.py?
def echo(value=None):
? ? print "Execution starts when 'next()' is called for the first time."
? ? try:
? ? ? ? while True:
? ? ? ? ? ? try:
? ? ? ? ? ? ? ? value = (yield value)
? ? ? ? ? ? except Exception, e:
? ? ? ? ? ? ? ? print "catched an exception", e
? ? ? ? ? ? ? ? value = e
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? print "yield received ", value
? ? finally:
? ? ? ? print "Don't forget to clean up when 'close()' is called."
?
generator = echo(1)
print generator.next()
print generator.next()
print generator.send(2)
generator.throw(TypeError, "spam")
generator.close()
[dongsong@localhost python-study]$?
[dongsong@localhost python-study]$?
[dongsong@localhost python-study]$ !python
python yield.py?
Execution starts when 'next()' is called for the first time.
1
yield received? None
None
yield received? 2
2
catched an exception spam
Don't forget to clean up when 'close()' is called.?
?
57.元類metaclass詳解見文章 http://blog.csdn.net/xiarendeniao/article/details/9232021??
58.單件模式的實現,棧溢出上這個帖子介紹了四種方式,我比較中意第三種http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python?
?
[dongsong@localhost python_study]$ cat singleton3.py?
#encoding=utf-8
?
class Singleton(type):
? ? ? ? _instances = {}
? ? ? ? def __call__(cls, *args, **kwargs):
? ? ? ? ? ? ? ? if cls not in cls._instances:
? ? ? ? ? ? ? ? ? ? ? ? cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
? ? ? ? ? ? ? ? return cls._instances[cls]
?
class MyClass(object):
? ? ? ? __metaclass__ = Singleton
?
singletonObj = Singleton('Test',(),{})
myClassObj1 = MyClass()
myClassObj2 = MyClass()
print singletonObj, singletonObj.__class__
print id(myClassObj1),myClassObj1,myClassObj1.__class__
print id(myClassObj2),myClassObj2,myClassObj2.__class__
[dongsong@localhost python_study]$ vpython singleton3.py?
<class '__main__.Test'> <class '__main__.Singleton'>
139799414931408 <__main__.MyClass object at 0x7f2596777fd0> <class '__main__.MyClass'>
139799414931408 <__main__.MyClass object at 0x7f2596777fd0> <class '__main__.MyClass'>59.python magic methods ,有些長,單開一篇文章
?http://blog.csdn.net/xiarendeniao/article/details/9270407
?
60.struct 二進制 官方文檔? http://docs.python.org/3/library/struct.html??
?
CharacterByte orderSizeAlignment@nativenativenative=nativestandardnone<little-endianstandardnone>big-endianstandardnone!network (= big-endian)standardnone?
?
?
FormatC TypePython typeStandard sizeNotesxpad byteno value? ccharbytes of length 11 bsigned? charinteger1(1),(3)Bunsigned? charinteger1(3)?_Boolbool1(1)hshortinteger2(3)Hunsigned? shortinteger2(3)iintinteger4(3)Iunsigned? intinteger4(3)llonginteger4(3)Lunsigned? longinteger4(3)qlong? longinteger8(2), (3)Qunsigned? longlonginteger8(2), (3)nssize_tinteger (4)Nsize_tinteger (4)ffloatfloat4(5)ddoublefloat8(5)schar[]bytes? pchar[]bytes? Pvoid? *integer (6)?
?
>>> import struct
>>> struct.pack('HH',1,2)
'\x01\x00\x02\x00'
>>> struct.pack('<HH',1,2)
'\x01\x00\x02\x00'
>>> struct.pack('>HH',1,2)
'\x00\x01\x00\x02'
>>> s= struct.pack('HH',1,2)
>>> s
'\x01\x00\x02\x00'
>>> len(s)
4
>>> struct.unpack('HH',s)??
(1, 2)
>>> struct.unpack_from('H', s, 2)?
(2,)
>>> struct.unpack('H',s[0:2])
(1,)??
61.閉包?
?
[dongsong@localhost python_study]$ cat enclosing_1.py?
#encoding=utf8
a = 1
b = 2
?
def f(v = 0):
? ? ? ? a = 2
? ? ? ? c = list()
? ? ? ? def g():
? ? ? ? ? ? ? ? print 'a = %s' % a
? ? ? ? ? ? ? ? print 'b = %s' % b
? ? ? ? ? ? ? ? print 'c = %r' % c
?
? ? ? ? if v == 0:
? ? ? ? ? ? ? ? a += 1
? ? ? ? else:
? ? ? ? ? ? ? ? a += v
? ? ? ? c.append(111)
? ? ? ? return g
?
g = f() #函數返回g函數對象賦值給g; 函數對象g跟a(3)、c([111])綁定構成閉包
f(10)() #內嵌對象跟a(12)、c([111])綁定構成閉包;輸出: a=12, b=2, c=[111]
f()? ? ?#沒有任何輸出,內嵌函數跟a/c綁定后的結果沒有使用
g()? ? ?#輸出: a = 3, b = 2, c = [111]
b = 3
g() #輸出: a = 3, b = 3, c = [111] (b是全局變量)
?
print a #輸出全局變量: a = 1
[dongsong@localhost python_study]$ vpython enclosing_1.py?
a = 12
b = 2
c = [111]
a = 3
b = 2
c = [111]
a = 3
b = 3
c = [111]
1?
62.如何阻止pyc跟py文件同居?看棧溢出的討論帖http://stackoverflow.com/questions/3522079/changing-the-directory-where-pyc-files-are-created?
python3.2之后可以在代碼目錄加一個__pycache__目錄,pyc文件會分居到這個目錄下(應該是這個意思,python3我沒用過)?
python2的話可以在啟動解釋器的時候加上-B參數阻止pyc字節碼文件寫盤,不過這樣勢必會導致import變慢(重新編譯)?
63.微博數據(賬號描述)入庫報警告且數據被截斷:?
?
[dongsong@localhost tfengyun_py]$ vpython new_user.py debug 1852589841
/data/weibofengyun/workspace-php/tfengyun_py/utils.py:26: Warning: Incorrect string value: '\xF0\x9F\x92\x91\xE4\xBD...' for column 'description' at row 1
? try: affectCount = self.cursor.execute(sql)?
最終解決辦法(直接從Python群里copy來的):?
?
嚇人的鳥(362278013) 11:27:58?
對于昨天那個數據入庫Mysql報Warning的問題大概整明白了,現分享如下,非常感謝@墨跡 !!
?
http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html?
mysql5.5.3之前不支持utf8mb4,上周五那個入庫警告是因為有部分unicode字符(ios設備的emoji表情)編碼成utf-8以后占四字節(正常一般不超過三字節):
>>> u'\u8bb0'.encode('utf-8')
'\xe8\xae\xb0'
>>> u'\U0001f497'.encode('utf-8')
'\xf0\x9f\x92\x97'
對于不想升級mysql版本來解決問題的情況,可以把這種字符過濾掉,棧溢出上有相關討論
http://stackoverflow.com/questions/10798605/warning-raised-by-inserting-4-byte-unicode-to-mysql
?
那么對于同一個Mysql數據庫和一樣的數據,為什么PHP程序可以正常入庫(不報錯不報警告、數據不被截斷)呢?
原來是因為它內部自動的把utf8的四字節編碼部分過濾掉了,入庫以后在mysql命令行下查詢會發現那些emoji表情符不見了,用PHP程序從數據庫把數據查出來驗證也確實如此
?
PS: 知之為知之,不知為不知,是知也.? 來提問的都是因為比較著急了,希望各位同仁少些說教,多些實際有效建議。
?
64.(2014.4.25)Python跟C/C++的混合使用(Python使用C/C++擴展,C/C++嵌套Python),最基本的用法當然是參照官網來做了,我有兩個對官網相關文檔的翻譯,巨麻煩!引用什么的規則太多了,這種低級接口不適宜在項目中直接使用。?
項目中首選Boost.Python(http://www.boost.org/doc/libs/1_55_0/libs/python/doc/),用過C++的應該對Boost不陌生,我對Boost的理解是僅次于C++標準庫的標準庫(09年老成在昆侖寫的聊天服用的就是boost.asio)。其中提供了對Python語言的支持。金山的C++/Python游戲服務器就是用的這個庫實現C++跟Python之間交互。?
其次,聽一個同學講他們項目(貌似非游戲項目)中有用到Pyrex(http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/version/Doc/About.html),這是一種類似于C和Python語法混寫的新語言,沒深入了解過,暫且擱下,我還是對Boost.Python比較感興趣。??
?
Cython(http://cython.org/) 基于Pyrex,被設計用來編寫python的c擴展??
說到這里不得不提一下pypy(http://pypy.org/)了(雖然pypy不是用來跟c/c++交互的),pypy是python實現的python解釋器,jit(Just-in-time compilation,動態編譯)使其運行速度比cpython(官方解釋器,一般人用的解釋器)要快,支持stackless、提供微線程協作,感覺前景一片光明啊!有消息說pypy會丟棄GIL以提升多線程程序的性能,不過我看官方文檔好像沒這么說(http://pypy.org/tmdonate2.html#what-is-the-global-interpreter-lock)。??
??
65.exec直接就可以執行代碼片段?
eval執行的是單條表達式?
compile可以把代碼片段或者代碼文件編譯成codeobject,exec和eval都可以執行codeobject?
https://docs.python.org/2/library/functions.html#compile??
?
?
[dongsong@localhost python-study]$ python
Python 2.6.6 (r266:84292, Jan 22 2014, 09:42:36)?
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = file("code.py").read()
>>> print s
def func():
? ? ? ? print "i am in function func()"
? ? ? ? return 1,2,3
?
>>> codeObj = compile(s,"<string>","exec")??
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'codeObj', 's']
>>> codeObj
<code object <module> at 0x7f761cd74738, file "<string>", line 1>
>>> eval(codeObj)
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'codeObj', 'func', 's']
>>> func()
i am in function func()
(1, 2, 3)
?
[dongsong@localhost python-study]$ python
Python 2.6.6 (r266:84292, Jan 22 2014, 09:42:36)?
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = file("code.py").read()
>>> exec(s)
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'func', 's']
>>> func()
i am in function func()
(1, 2, 3)?
66.隨機字符串 http://stackoverflow.com/questions/2257441/random-string-generation-with-upper-case-letters-and-digits-in-python?
?
>>> import string
>>> import random
>>> def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
...? ? return ''.join(random.choice(chars) for _ in range(size))
...
>>> id_generator()
'G5G74W'
>>> id_generator(3, "6793YUIO")
'Y3U'
>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.digits
'0123456789'
>>> string.ascii_uppercase + string.digits
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
>>> string.lowercase
'abcdefghijklmnopqrstuvwxyz'?
67.內建函數hasattr不能查找對象的私有屬性(2014.6.18)?
?
[dongsong@localhost python-study]$ cat hasattr.py
#encoding=utf-8
?
class A(object):
? ? def __init__(self):
? ? ? ? self.__a = 100
? ? ? ? self.a = 200
? ? def test(self):
? ? ? ? if hasattr(self,'__a'): print 'found self.__a:',self.__a
? ? ? ? else: print 'not found self.__a'
? ? ? ? if hasattr(self,'a'): print 'found self.a:', self.a
? ? ? ? else: print 'not found self.a:', self.a
?
if __name__ == '__main__':
? ? t = A()
? ? t.test()
[dongsong@localhost python-study]$?
[dongsong@localhost python-study]$ python hasattr.py?
not found self.__a
found self.a: 200?
68.Python循環import : Circular (or cyclic) imports??
http://stackoverflow.com/questions/744373/circular-or-cyclic-imports-in-python?
說白了,a import b, b import a, 那么在a的主代碼塊(也就是“import a”時會被執行的代碼)中使用module b里面的符號(b.xx、from b import xx)會出錯。?
另,python a.py,那么a.py初次會當做__main__ module,“import a”會重新把a執行一遍(這個在源碼剖析里面有提到,也就是使用if __name__ == '__main__'判斷的原因)?
?
[root@test-22 xds]# cat maintest.py
import maintest
print 'main test in ..'
if __name__ == '__main__':
? ? print 'aaaa'
print 'main test out..'
[root@test-22 xds]#?
[root@test-22 xds]# python maintest.py
main test in ..
main test out..
main test in ..
aaaa
main test out..