python奇技淫巧


 

  本文用作記錄,在使用python過程中遇到的一些奇技淫巧,有些代碼是本人所寫,有些則是python內置函數,有些則取之互聯網。在此記錄,只為備份以及遺忘時方便查找。
  本文將會持續更新,內容僅限記錄一些常用好用卻又永遠記不住的代碼或者模塊。

 

控制台操作

控制台不閃退

1
os.system( 'pause')

 

獲取控制台大小

1
rows, columns = os.popen( 'stty size', 'r'). read().split()

 

輸入輸出控制

解決輸入提示中文亂碼問題

1
raw_input(unicode( '請輸入文字', 'utf-8').encode( 'gbk'))

 

格式化輸出

1
print a.prettify()

 

接受多行輸入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
text= ""
while 1:
data=raw_input( ">>")
if data.strip()== "stop":
break
text+= "%s\n" % data
print text
---------------------------
>>1
>>2
>>3
>>stop
1
2
3

 

同行輸出

1
2
Print '%s' % a,
Print '%s \r' % a

 

標准輸入輸出

1
2
sys.stdout.write( "input") 標准輸入
sys.stdout.flush() 刷新緩沖區

 

print的功能與sys.stdout.write類似,因為2.x中print默認就是將輸出指定到標准輸出中(sys.stdout)。

顏色控制

控制台顏色控制(適用於windows)

1
2
3
4
WConio.textcolor(WConio.YELLOW)
print "yellow"
WConio.textcolor(WConio.BLUE)
print "blue"

 

輸出顏色控制(全平台)

1
2
3
4
5
6
7
8
red = '\033[1;31m'
green = '\033[1;32m'
yellow = '\033[1;33m'
white = '\033[1;37m'
reset = '\033[0m’
 
print red+"color is red"+reset
print green+"color is green"+reset

 

進度條控制

方案一

1
2
3
4
5
6
7
8
from __future__ import division
import sys,time
j = '#'
for i in range(1,61):
j += '#'
sys.stdout.write(str(int((i/60)*100))+ '% ||'+j+ '->'+ "\r")
sys.stdout.flush()
time.sleep(0.1)

 

方案二

1
2
3
4
5
6
import sys
import time
for i in range(1,61):
sys.stdout.write( '#'+ '->'+ "\b\b")
sys.stdout.flush()
time.sleep(0.5)

 

方案三

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from progressbar import *
import time
import os
rows, columns = os.popen( 'stty size', 'r'). read().split() #獲取控制台size
console_width=int(columns)
total = 10
progress = ProgressBar()
 
def test():
'' '
進度條函數,記錄進度
' ''
for i in progress(range(total)):
test2()
 
def test2():
'' '
執行函數,輸出結果
' ''
content= "nMask'Blog is http://thief.one"
sys.stdout.write( "\r"+content+ " "*(console_width-len(content)))
time.sleep(1)
sys.stdout.flush()
 
test()

 

更多高級用法可以使用progressbar模塊。

系統操作

系統信息

獲取python安裝路徑

1
2
from distutils.sysconfig import get_python_lib
print get_python_lib

 

獲取當前python版本

1
2
sys.version_info
sys.version

 

獲取當前時間

1
2
3
4
c=time.ctime()
#自定義格式輸出
ISOTIMEFORMAT=’%Y-%m-%d %X’
time.strftime( ISOTIMEFORMAT, time.localtime() )

 

查看系統環境變量

1
os.environ[ "PATH"]

 

獲取系統磁盤

1
os.popen( "wmic VOLUME GET Name")

 

獲取當前路徑(包括當前py文件名)

1
os.path.realpath(__file__)

 

當前平台使用的行終止符

1
os.linesep

 

獲取終端大小

1
2
3
rows, columns = os.popen( 'stty size', 'r'). read().split()
#python3以后存在可以使用os
os.get_termial_size()

 

退出程序

  • return:返回函數的值,並退出函數。
  • exit():直接退出。
  • sys.exit(): 引發一個SystemExit異常,若沒有捕獲錯誤,則python程序直接退出;捕獲異常后,可以做一些額外的清理工作。
  • sys.exit(0):為正常退出,其他(1-127)為不正常,可拋異常事情供捕獲。(一般用於主線程中退出程序)
  • os._exit(0): 直接退出python程序,其后的代碼也不會執行。(一般用於線程中退出程序)

網絡操作

域名解析為ip

1
ip= socket.getaddrinfo(domain, 'http')[0][4][0]

 

獲取服務器版本信息

1
2
3
sUrl = 'http://www.163.com'
sock = urllib2.urlopen(sUrl)
sock.headers.values()

 

文件操作

open函數,使用wb、rb代替w、r

1
2
with open( "test.txt", "wr") as w:
w.write( "test")

 

這種寫法可以兼容python2/3。
輸出一個目錄下所有文件名稱

1
2
3
4
5
6
7
8
def search(paths):
if os.path.isdir(paths): #如果是目錄
files=os.listdir(paths) #列出目錄中所有的文件
for i in files:
i=os.path.join(paths,i) #構造文件路徑
search(i) #遞歸
elif os.path.isfile(paths): #如果是文件
print paths #輸出文件名

 

文件查找

1
2
3
4
5
6
import glob
print glob.glob(r "E:/*.txt") #返回的是一個列表
查找文件只用到三個匹配符:”*”, “?”, “[]“
”*”匹配0個或多個字符;
”?”匹配單個字符;
”[]“匹配指定范圍內的字符,如:[0-9]匹配數字。

 

查找指定名稱的文件夾的路徑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def search(paths,file_name,tag,lists):
if os.path.isdir(paths): #如果是目錄
if file_name==tag: #如果目錄名稱為tag
lists.append(paths) #將該路徑添加到列表中
else: #如果目錄名稱不為tag
try:
files_list=os.listdir(paths) #列出目錄中所有的文件
for file_name in files_list:
path_new=os.path.join(paths,file_name) #構造文件路徑
search(path_new,file_name,tag,lists) #遞歸
except: #遇到特殊目錄名時會報錯
pass
 
elif os.path.isfile(paths): #如果是文件
pass
 
return lists

 

數據操作

判斷數據類型

1
isinstance( "123",(int,long, float,complex)

 

字符串(string)

字符串推導

1
2
3
4
a= "True"
b=a if a== "True" else "False"
>>> print b
True

 

format方法拼接字符串與變量

1
2
3
4
5
6
7
a= "{test} abc {test2}".format( test= "123",test2= "456")
>>>> print a
123 abc 456
或者:
a= "{},{}".format(1,2)
>>>>> print a
1,2

 

去掉小數點后面的數字

1
2
a=1.21311
b=Int(math.floor(a))

 

字符串倒置

1
2
>>> a = "codementor"
>>> a[::-1]

 

字符串首字母變大寫

1
2
3
info = 'ssfef'
print info.capitalize()
print info.title()

 

返回一個字符串居中,並使用空格填充至長度width的新字符串。

1
"center string".center(width) #width設置為控制台寬度,可控制輸出的字符串居中。

 

列舉所有字母

1
2
3
print string.ascii_uppercase 所有大寫字母
print string. ascii_lowercase 所有小寫字母
print string.ascii_letters 所有字母(包括大小寫)

 

列表(list)

列表去重

1
2
ids = [1,4,3,3,4,2,3,4,5,6,1]
ids = list( set(ids))

 

判斷列表為空

1
2
a=[]
if not a:

 

列表運算

1
2
3
4
5
a=[1,2,3]
b=[3,4,5]
set(a)& set(b) 與
set(a)| set(b) 或
set(a)- set(b) 非

 

單列表元素相加

1
2
3
a = [ "Code", "mentor", "Python", "Developer"]
>>> print " ".join(a)
Code mentor Python Developer

 

多列表元素分別相加

1
2
3
4
5
6
7
8
list1 = [ 'a', 'b', 'c', 'd']
list2 = [ 'p', 'q', 'r', 's']
>>> for x, y in zip(list1,list2):
print x, y
ap
bq
cr
ds

 

將嵌套列表轉換成單一列表

1
2
3
4
a = [[1, 2], [3, 4], [5, 6]]
>>> import itertools
>>> list(itertools.chain.from_iterable(a))
[1, 2, 3, 4, 5, 6]

 

列表內元素相加

1
2
a=[1,2,3](數字)
sum(a)

 

產生a-z的字符串列表

1
map(chr,range(97,123))

 

列表復制

1
2
3
a=[1,2,3]
b=a
當對b進行操作時,會影響a的內容,因為共用一個內存指針,b=a[:] 這樣就是單獨復制一份了。

 

列表推導

if+else配合列表解析

1
[i if i >5 else -i for i in range(10)]

 

多層嵌套列表

1
2
3
4
a=[[1,2],[3,4]]
b=[ for j in i for i in a]
print b
[1,2,3,4]

 

生成一個生成器,調用next方法,可以減少內存開支。

1
a=(i else i+1 for i in b if i==1)

 

字典推導

更換key與value位置

1
2
dict={ "a":1, "b":2}
b={value:key for key value in dict.items()}

 

字典操作(dict)

篩選出值重復的key

1
2
3
4
5
6
list1=self.dict_ip.items()
ddict=defaultdict(list)
for k,v in list1:
ddict[v].append(k)
list2=[(i,ddict[i]) for i in ddict if len(ddict[i])>1]
dict_ns=dict(list2)

 

字典排序(py2)

1
2
file_dict={ "a":1, "b":2, "c":3}
file_dict_new=sorted(file_dict.iteritems(), key=operator.itemgetter(1),reverse=True) ##字典排序,reverse=True由高到低,itemgetter(1)表示按值排序,為0表示按key排序。

 

字典值判斷

1
2
3
b={ "a":1}
a=b.get( "a", "") #如果不存在a,則返回””
c=a if a else 0 #如果存在a,則返回a,不然返回0

 

模塊操作

導入模塊時,設置只允許導入的屬性或者方法。

1
2
3
4
5
6
7
8
9
10
fb.py:
-----------------------
__all__=[ "a", "b"]
a= "123"
c= "2345"
def b():
print “123”
-----------------------
from fb import *
可以導入__all__內定義的變量,a跟b()可以導入,c不行。如果不定義__all__則所有的都可以導入。

 

導入上級目錄下的包

1
2
sys.path.append( "..")
from spider.spider_ import spider_

 

導入外部目錄下的模塊

1
需要在目標目錄下創建__init__.py文件,內容隨便。

 

增加模塊屬性

1
2
3
4
有時候源代碼中,我們需要寫上自己的名字以及版本介紹信息,可以用__name__的方式定義。
a.py:
#! -*- coding:utf-8 -*-
__author__= "nMask"

 

然后當我們導入a這個模塊的時候,可以輸出dir(a)看看

1
2
3
4
5
>>> import p
>>> print dir(p)
[ '__author__', '__builtins__', '__doc__', '__file__', '__name__', '__package__']
>>> print p.__author__
nmask

 

動態加載一個目錄下的所有模塊

1
2
3
4
5
6
7
8
9
10
11
目錄:
--- test
----a.py
----b.py
---c.py
c.py導入 test下面的所有模塊:
for path in [ "test"]:
for i in list( set([os.path.splitext(i)[0] for i in os.listdir( "./"+path)])):
if i!= "__init__" and i!= ".DS_Store": ##排除不必要的文件
import_string = "import path+". "+i+"
exec import_string #執行字符串中的內容

 

函數操作

eval/exec

1
2
3
4
def test(content):
print content
 
exec(“ test(‘abc ')”)

輸出:abc
說明:exec函數沒有返回值

1
2
3
4
def test(content):
return content
 
print eval(“ test(‘abc ')”)

 

輸出:abc
說明:eval函數有返回值

裝飾器函數

輸出當前時間裝飾器

1
2
3
4
5
def current_time(aclass):
def wrapper():
print "[Info]NowTimeis:",time.ctime()
return aclass()
return wrapper

 

itertools迭代器

1
2
3
p=product([ "a", "b", "c", "d"],repeat=2)
----
[( "a", "a"),( "b", "b")......]

reduce函數

函數本次執行的結果傳遞給下一次。

1
2
3
4
def test(a,b):
return a+b
reduce( test,range(10))
結果:從0+1+2......+9

 

enumerate函數

輸入列表元素以及序列號

1
2
3
n=[ "a", "b", "c"]
for i,m in enumerate(n):
print(i,m)

 

函數超時時間設置

@於2017.05.27更新
利用signal設置某個函數執行的超時時間

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import time
import signal
 
def test(i):
time.sleep(0.999) #模擬超時的情況
print "%d within time"%(i)
return i
 
def fuc_time(time_out):
# 此為函數超時控制,替換下面的test函數為可能出現未知錯誤死鎖的函數
def handler(signum, frame):
raise AssertionError
try:
signal.signal(signal.SIGALRM, handler)
signal.alarm(time_out) #time_out為超時時間
temp = test(1) #函數設置部分,如果未超時則正常返回數據,
return temp
except AssertionError:
print "%d timeout"%(i) # 超時則報錯
 
if __name__ == '__main__':
for i in range(1,10):
fuc_time(1)

 

函數出錯重試

利用retrying模塊實現函數報錯重試功能

1
2
3
4
5
6
7
8
import random
from retrying import retry
 
@retry
def have_a_try():
if random.randint(0, 10) != 5:
raise Exception( 'It's not 5! ')
print 'It 's 5!'

 

如果我們運行have_a_try函數,那么直到random.randint返回5,它才會執行結束,否則會一直重新執行,關於該模塊更多的用法請自行搜索。

程序操作

@於2017.05.27更新

Ctrl+C退出程序

利用signal實現ctrl+c退出程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import signal
import sys
import time
 
def handler(signal_num,frame):
print "\nYou Pressed Ctrl-C."
sys.exit(signal_num)
signal.signal(signal.SIGINT, handler)
 
# 正常情況可以開始你自己的程序了。
# 這里為了演示,我們做一個不會卡死機器的循環。
while 1:
time.sleep(10)
# 當你按下Ctrl-C的時候,應該會輸出一段話,並退出.

 

程序自重啟

利用os.execl方法實現程序自重啟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import time
import sys
import os
 
def restart_program():
python = sys.executable
print "info:",os.execl(python, python, * sys.argv)
#os.execl方法會代替自身進程,以達到自重啟的目的。
 
if __name__ == "__main__":
print 'start...'
print u "3秒后,程序將結束...".encode( "utf8")
time.sleep(3)
restart_program()

 

內容來自博客:http://thief.one/2017/04/19/1/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM