pythoncc
1. python 怎麼讓程序接受ctrl + c終止信號
花了一天時間用python為服務寫了個壓力測試。很簡單,多線程向伺服器發請求。但寫完之後發現如果中途想停下來,按Ctrl+C達不到效果,自然想到要用信號處理函數捕捉信號,使線程都停下來,問題解決的方法請往下看:
復制代碼代碼如下:
#!/bin/env python
# -*- coding: utf-8 -*-
#filename: peartest.py
import threading, signal
is_exit = False
def doStress(i, cc):
global is_exit
idx = i
while not is_exit:
if (idx < 10000000):
print "thread[%d]: idx=%d"%(i, idx)
idx = idx + cc
else:
break
print "thread[%d] complete."%i
def handler(signum, frame):
global is_exit
is_exit = True
print "receive a signal %d, is_exit = %d"%(signum, is_exit)
if __name__ == "__main__":
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
cc = 5
for i in range(cc):
t = threading.Thread(target=doStress, args=(i,cc))
t.start()
上面是一個模擬程序,並不真正向服務發送請求,而代之以在一千萬以內,每個線程每隔並發數個(cc個)列印一個整數。很明顯,當所有線程都完成自己的任務後,進程會正常退出。但如果我們中途想退出(試想一個壓力測試程序,在中途已經發現了問題,需要停止測試),該腫么辦?你當然可以用ps查找到進程號,然後kill -9殺掉,但這樣太繁瑣了,捕捉Ctrl+C是最自然的想法。上面示常式序中已經捕捉了這個信號,並修改全局變數is_exit,線程中會檢測這個變數,及時退出。
但事實上這個程序並不work,當你按下Ctrl+C時,程序照常運行,並無任何響應。網上搜了一些資料,明白是python的子線程如果不是daemon的話,主線程是不能響應任何中斷的。但設為daemon後主線程會隨之退出,接著整個進程很快就退出了,所以還需要在主線程中檢測各個子線程的狀態,直到所有子線程退出後自己才退出,因此上例29行之後的代碼可以修改為:
復制代碼代碼如下:
threads=[]
for i in range(cc):
t = threading.Thread(target=doStress, args=(i, cc))
t.setDaemon(True)
threads.append(t)
t.start()
for i in range(cc):
threads[i].join()
重新試一下,問題依然沒有解決,進程還是沒有響應Ctrl+C,這是因為join()函數同樣會waiting在一個鎖上,使主線程無法捕獲信號。因此繼續修改,調用線程的isAlive()函數判斷線程是否完成:
復制代碼代碼如下:
while 1:
alive = False
for i in range(cc):
alive = alive or threads[i].isAlive()
if not alive:
break
這樣修改後,程序完全按照預想運行了:可以順利的列印每個線程應該列印的所有數字,也可以中途用Ctrl+C終結整個進程。完整的代碼如下:
復制代碼代碼如下:
#!/bin/env python
# -*- coding: utf-8 -*-
#filename: peartest.py
import threading, signal
is_exit = False
def doStress(i, cc):
global is_exit
idx = i
while not is_exit:
if (idx < 10000000):
print "thread[%d]: idx=%d"%(i, idx)
idx = idx + cc
else:
break
if is_exit:
print "receive a signal to exit, thread[%d] stop."%i
else:
print "thread[%d] complete."%i
def handler(signum, frame):
global is_exit
is_exit = True
print "receive a signal %d, is_exit = %d"%(signum, is_exit)
if __name__ == "__main__":
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
cc = 5
threads = []
for i in range(cc):
t = threading.Thread(target=doStress, args=(i,cc))
t.setDaemon(True)
threads.append(t)
t.start()
while 1:
alive = False
for i in range(cc):
alive = alive or threads[i].isAlive()
if not alive:
break
其實,如果用python寫一個服務,也需要這樣,因為負責服務的那個線程是永遠在那裡接收請求的,不會退出,而如果你想用Ctrl+C殺死整個服務,跟上面的壓力測試程序是一個道理。總結一下,python多線程中要響應Ctrl+C的信號以殺死整個進程,需要:
1.把所有子線程設為Daemon;
2.使用isAlive()函數判斷所有子線程是否完成,而不是在主線程中用join()函數等待完成;
3.寫一個響應Ctrl+C信號的函數,修改全局變數,使得各子線程能夠檢測到,並正常退出。
2. 使用gmail 的 python 腳本,sendmail 的 cc應該怎麼寫
defsend_plain_mail(recp,cc,subject,content):
"""
SendmailfromSMTPserver
"""
importsocket
socket.setdefaulttimeout(60)
msg=email.Message.Message()
msg['From']=user
msg['to']=recp
msg['cc']=cc+recp#onemethodis:addCCuserhere
msg['date']=time.ctime()
msg['subject']=email.Header.Header(subject,'gbk')
body=email.MIMEText.MIMEText(content,_charset='gbk')
try:
server=smtplib.SMTP(SMTP_SERVER,587)
#Thefollowing3linesisforgmail
server.ehlo()
server.starttls()
server.ehlo()
server.login(user,password)
server.sendmail(user,string.split(recp,","),msg.as_string()[:-1]+body.as_string())
return
exceptException,e:
print"From:",user,"To:",recp,"",Exception,":",str(e)
return
3. 在python語言中CC=O*84 則print(CC)=
要怎麼做可不是幾句話能說清楚的,首先你要會VFP程序編程,要對VFP了解。然後對於做一個可運行的系統,首先要建立項目,再在項目中建立相應的資料庫、表,然後建立表單,編製程序,最後連編成可執行文件。
4. python腳本運行出現問題
數字for
cc
in
(1,2)意思CC取值從1到2。
這里字母被python當作了變數,a和b都沒有定義,python當然不知道了。
5. Python中元組常用的方法有哪些,分別有什麼作用
元組特點:定義元組使用小括弧,且逗號隔開各個數據,數據可以是不同的數據類型
如果定義的元組只有一個數據也需要加逗號,否則數據類型為唯一的這個數據的數據類型
元組中的數據是不可以刪除,修改的
如果要存儲對個數據,但這些數據是不能修改的數據就使用元組
使用方法:
1、查找 元組數據不支持修改,只支持查找
按下標查找數據
index()
count()
len()
# 1,按下標查找數據
tuplel = ('aa','bb','cc','dd')
print(tuplel[0]) # aa
# 2,index():查找某個數據,如果數據存在返回對應的下標,否則報錯,語法和列表,字元串的index方法相同
tuplel = ('aa','bb','cc','bb')
print(tuplel.index('aa')) # 0
# 3,count():統計某個數據在當前元組中出現的次數
tuplel = ('aa','bb','cc','bb')
print(tuplel.count('bb')) # 2
# 4,len()
print(len(tuplel)) # 4--tuplel 中有4個數據
2、修改
元組內的直接數據如果修改則立即報錯
但是如果元組裡面有列表,修改列表裡面的數據則是支持的,
t1 = ('aa','bb','cc','dd')
# t1[0] = 'aaa' # 直接報錯,列表數據不允許修改
t2 = ('aa','bb',['cc','dd'])
print(t2)
print(t2[2][0])
t2[2][0] = 'xiaoguai'
print(t2)
6. Python cc={'a':['100','200']} 在這個字典中,怎麼添加一個值在列表裡
cc['a'].append(值)
7. python 列印出函數執行所用時間
使用timeit模塊,先介紹下:
timeit 模塊
timeit模塊定義了接受兩個參數的Timer類。兩個參數都是字元串。 第一個參數是你要計時的語句或者函數。 傳遞給Timer的第二個參數是為第一個參數語句構建環境的導入語句。 從內部講,timeit構建起一個獨立的虛擬環境, 手工地執行建立語句,然後手工地編譯和執行被計時語句。
一旦有了Timer對象,最簡單的事就是調用timeit(),它接受一個參數為每個測試中調用被計時語句的次數,默認為一百萬次;返回所耗費的秒數。
Timer對象的另一個主要方法是repeat(), 它接受兩個可選參數。 第一個參數是重復整個測試的次數,第二個參數是每個測試中調用被計時語句的次數。 兩個參數都是可選的,它們的默認值分別是3和1000000。repeat()方法返回以秒記錄的每個測試循環的耗時列表。Python有一個方便的min函數可以把輸入的列表返回成最小值,如: min(t.repeat(3, 1000000))
你可以在命令行使用timeit模塊來測試一個已存在的Python程序,而不需要修改代碼。
再給你個例子,你就知道怎麼做了。
#-*-coding:utf-8-*-
#!/bin/envpython
deftest1():
n=0
foriinrange(101):
n+=i
returnn
deftest2():
returnsum(range(101))
deftest3():
returnsum(xforxinrange(101))
if__name__=='__main__':
fromtimeitimportTimer
t1=Timer("test1()","from__main__importtest1")
t2=Timer("test2()","from__main__importtest2")
t3=Timer("test3()","from__main__importtest3")
printt1.timeit(1000000)
printt2.timeit(1000000)
printt3.timeit(1000000)
printt1.repeat(3,1000000)
printt2.repeat(3,1000000)
printt3.repeat(3,1000000)
8. python語句問題,請問這段是什麼意思,如何理解它
如果傳遞給構造函數的參數output_size是int類型的變數,就給類定義一個同名的屬性output_size,其值是元組(output_size,output_size)。
否則,這個屬性的值與參數output_size的值相同。
比如:
cc=CenterCrop(666)
則cc.output_size就等於(666,666)。
而對於cc2=CenterCrop("888"),cc2.output_size就等於"888"。
9. python 如何使用生成器函數實現可迭代對象
Iamlaosong文
我們在用for ... in ...語句循環時,in後面跟隨的對象要求是可迭代對象,即可以直接作用於for循環的對象統稱為可迭代對象(Iterable),如list、tuple、dict、set、str等。
可迭代對象是實現了__iter__()方法的對象,而迭代器(Iterator)則是實現了__iter__()和__next__()方法的對象,可以顯示地獲取下一個元素。這種可以被next調用並不斷返回下一個值的對象稱為迭代器。迭代器一定是可迭代對象,反過來則不一定成立。用iter()函數可以把list、dict、str等Iterable變成Iterator,例如:
bb=[x for x in range(10)]
cc=iter(bb)
cc.next()
循環變數的值其實可以看著是一次次用next取值的過程,每取一個值,做一次處理。list等對象用於循環實際上可以看著是用iter()方法產生一個迭代器,然後循環取值。
生成器(generator)就是一個能返回迭代器的函數,其實就是定義一個迭代演算法,可以理解為一個特殊的迭代器。調用這個函數就得到一個迭代器,生成器中的yield相當於一個斷點,執行到此返回一個值後暫停,從而實現next取值。
10. Python 在編程語言中是什麼地位為什麼很多大學不教 Python
python的地位很高,目前是世界第5大編程語言。。但我覺得大學不教python,其實是正確的。
Python在誕生之初,只是用來在Linux上給Perl和shell做銜接用的「膠水」,而今天已經成為了主流的編程語言,能獲得今天的地位,當然具備諸多優勢。。。比如數學運算相關的各種庫,爬蟲,等等。。。但這都不是導致Python流行的最根本原因。
有沒有比Python運算更強的語言?多得是
有沒有比Python爬蟲效率更高的語言?也不少
所以其實平日里隨口道來的種種優勢,並不是不可替代的。。這些優勢,很多語言都具備。就比如perl,erlang,Julia等語言,其實用來做運算或爬蟲比Python更強,但為什麼這些語言卻流行不起來?
說到底,Python成功的秘訣只有一條,其實就是在功能基本夠用的前提下,比其他語言簡單。而比Python簡單的語言,功能又不夠全面,比如Lua,Javascript,Ruby這些語言比Python更簡單,但往往只適合一兩個領域的工作,而無法面面俱到。
Python可以提供的這些功能,對於非專業程序員來講,已經顯得非常強大了。。但對於專業程序員來說,Python最大的作用,其實也只是用來「偷懶」而已。因為相比JAVA或C#這種工業級的編程語言來講,Python除了入門簡單之外,並無任何優勢可言。而Python的動態語言特性、不利於維護等缺點,成為了限制它邁向深層開發的重大缺陷。
而如果熟練掌握JAVA或C#中的任何一門,想利用閑暇之餘學習一下Python,看幾個案例便可以入門,幾乎不需要專門學習。
如果你並不以成為專業程序員做為目標,那麼以Python為主,是可以的。但若想靠編程養家糊口,靜態語言才是重中之重。
但如果是計算機專業的話,僅僅學Python,似乎就有點對不起「科班出身」的稱號了。。。。學生們花著昂貴的學費,消耗四年光陰,卻只學個Python,豈不是誤人子弟?
就像你若報考攝影專業,老師應該教你使用單反,而不是教你使用手機攝像頭。