您好,登錄后才能下訂單哦!
這篇文章主要介紹“Python編程常用技巧有哪些”,在日常操作中,相信很多人在Python編程常用技巧有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Python編程常用技巧有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
一、字符串處理技巧
1. 清理用戶輸入
對輸入的的值進行清理處理,是常見的程序要求。比如要做大小寫轉(zhuǎn)化、要驗證輸入字符的注入,通??梢酝ㄟ^寫正則用Regex來做專項任務。但是對于復雜的情況,可以用一些技巧,比如下面:
user_input = "This\nstring has\tsome whitespaces...\r\n" character_map = { ord('\n') : ' ', ord('\t') : ' ', ord('\r') : None }
在此示例中,可以看到空格字符"\n"和"\t"都被替換為空格,而 "\r"被刪除。
這是一個簡單的示例,我們還可以使用unicodedata包和combinin()函數(shù)來生成大的映射表,以生成映射來替換字符串。
2. 提示用戶輸入
命令行工具或腳本需要輸入用戶名和密碼才能操作。要用這個功能,一個很有用的技巧是使用getpass模塊:
import getpass user = getpass.getuser() password = getpass.getpass()
這三行代碼就可以讓我們優(yōu)雅的交互提醒用戶輸入輸入密碼并捕獲當前的系統(tǒng)用戶和輸入的密碼,而且輸入密碼時候會自動屏蔽顯示,以防止被人竊取。
3. 查找字符串頻率
如果需要使用查找類似于某些輸入字符串的單詞,可以使用difflib來實現(xiàn):
import difflib difflib.get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'], n=2)
# 返回['apple', 'ape']
difflib.get_close_matches會查找相似度最匹配的字串。本例中,第一個參數(shù)與第二個參數(shù)匹配。提供可選參數(shù)n,該參數(shù)指定要返回的最大匹配數(shù),以及參數(shù)cutoff(默認值為0.6)設置為thr確定匹配字符串的分數(shù)。
4. 多行字符串
Python中可以使用反斜杠:
In [20]: multistr = " select * from test \ ...: where id < 5" In [21]: multistr Out[21]: ' select * from test where id < 5'
還可以使用三引號:
In [23]: multistr ="""select * from test ...: where id < 5""" In [24]: multistr Out[24]: 'select * test where id < 5'
上面方法共有的問題是缺少合適的縮進,如果我們嘗試縮進會在字符串中插入空格。所以最后的解決方案是將字符串分為多行并且將整個字符串包含在括號中:
In [25]: multistr = ("select * from multi_row " ...: "where row_id < 5 " ...: "order by age") In [26]: multistr Out[26]: 'select * from multi_row where row_id < 5 order by age'
5. 處理IP地址
日常常用的一個是驗證和匹配IP地址,這個功能有個專門的模塊ipaddress可以來處理。比如我們要用IP網(wǎng)段(CIDR用IP和掩碼位)生成一個IP地址列表:
import ipaddress net = ipaddress.ip_network('192.168.1.0/27')
結(jié)果:
#192.168.1.0 #192.168.1.1 #192.168.1.2 #192.168.1.3 #...
另一個不錯的功能IP地址是否在IP段的驗證:
ip = ipaddress.ip_address("192.168.1.2") ip in net # True ip = ipaddress.ip_address("192.168.1. 253") ip in net # False
ip地址轉(zhuǎn)字符串、整數(shù)值的互轉(zhuǎn):
>>> str(ipaddress.IPv4Address('192.168.0.1')) '192.168.0.1' >>> int(ipaddress.IPv4Address('192.168.0.1')) 3232235521 >>> str(ipaddress.IPv6Address('::1')) '::1' >>> int(ipaddress.IPv6Address('::1')) 1
注意ipaddress還支持很多其他的功能,比如支持ipv4和ipv6等,具體可以參考模塊的文檔。
二、性能優(yōu)化技巧
1. 限制CPU和內(nèi)存使用量
如果Python程序占用資源太大,想限制資源的使用,可以使用resource包。
# CPU限制 def time_exceeded(signo, frame): print("CPU 超額...") raise SystemExit(1) def set_max_runtime(seconds): soft, hard = resource.getrlimit(resource.RLIMIT_CPU) resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard)) signal.signal(signal.SIGXCPU, time_exceeded) # 限制內(nèi)存使用 def set_max_memory(size): soft, hard = resource.getrlimit(resource.RLIMIT_AS) resource.setrlimit(resource.RLIMIT_AS, (size, hard))
對CPU限制時候,先獲取特定資源(RLIMIT_CPU)的軟限制和硬限制,然后使用參數(shù)指定的秒數(shù)和獲取的硬限制來設置。如果超過CPU時間,將注冊導致系統(tǒng)退出的信號。
對內(nèi)存限制,也先獲取軟限制和硬限制,并用帶有size參數(shù)的setrlimit對其進行設置。
2. 通過__slots__節(jié)省內(nèi)存
如果程序中有一個類需要創(chuàng)建大量實例,那么可能會對內(nèi)存占用會非常大。因為Python使用字典來表示類實例的屬性,這可以加速執(zhí)行,但內(nèi)存效率很差,通常這不是問題??梢允褂胈_slots__來優(yōu)化:
import sys class FileSystem(object):
def __init__(self, files, folders, devices): self.files = files self.folders = folders self.devices = devices print(sys.getsizeof( FileSystem )) class FileSystem1(object): __slots__ = ['files', 'folders', 'devices'] def __init__(self, files, folders, devices): self.files = files self.folders = folders self.devices = devices print(sys.getsizeof( FileSystem1 ))
# Python 3.5下
#1-> 1016
#2-> 888
當定義__slots__屬性時,Python使用固定大小的數(shù)組作為屬性,而不用字典,這大大減少了每個實例所需的內(nèi)存。當然使用__slots__也有缺點,比如,無法聲明任何新屬性,而且只能在__slots__上使用它們,__slots__的類也不能使用多重繼承。
3. 用lru_cache緩存函數(shù)調(diào)用
都說Python性能差,尤其是一些計算的時候,其實是有一些通用的方法可以解決程序能的問題,比如緩存和記憶術(shù)。使用functools中的lru_cache可以解決迭代計算中大量重復迭代調(diào)用問題:
# CacheInfo(hits=2, misses=4, maxsize=32, currsize=4)
在上例中,我們執(zhí)行正在緩存的GET請求(最多3個緩存結(jié)果)。還使用cache_info方法檢查函數(shù)的緩存信息。裝飾器還提供了clear_cache方法,用于刪除緩存。
4. __all__控制import
某些語言支持import成員(變量,方法,接口)的機制。在Python中,默認所有內(nèi)容都會import,但是可以使用__all__來限制
def foo(): pass def bar(): pass __all__ = ["bar"]
通過這樣的方式我們可以限制從some_module import *使用時可以導入的內(nèi)容。該實例中,則僅import bar函數(shù)。如果將__all__保留為空,并且在使用通配符import時,不會import任何東西,會觸發(fā)AttributeError錯誤。
三、面向?qū)ο?/strong>
1. 創(chuàng)建支持With語句的對象
我們都知道如何使用打開或關(guān)閉語句,例如打開文件或獲取鎖,但是如何實現(xiàn)自己的方法呢?
可以使用__enter__和__exit__方法實現(xiàn):
class Connection: def __init__(self): ... def __enter__(self): # Initialize connection... def __exit__(self, type, value, traceback): # Close connection... with Connection() as c: # __enter__() executes ... # conn.__exit__() executes
這是在Python中實現(xiàn)上下文管理的最常見方法,但是有一種更簡單的方法:
from contextlib import contextmanager @contextmanager def tag(name): print(f"<{name}>") yield print(f"</{name}>") with tag("h2"): print("This is Title.")
上面的代碼段使用contextmanager管理器裝飾器實現(xiàn)了內(nèi)容管理協(xié)議。進入with塊時,執(zhí)行標記函數(shù)的第一部分(在yield之前),然后執(zhí)行該塊,最后執(zhí)行其余的標記函數(shù)。
2. 重載運算符號的技巧
考慮到有很多比較運算符:__lt__ , __le__ , __gt__,對于一個類實現(xiàn)所有比較運算符可能會很煩人。這時候可以使用functools.total_ordering:
from functools import total_ordering @total_ordering class Number: def __init__(self, value): self.value = value def __lt__(self, other): return self.value < other.value def __eq__(self, other): return self.value == other.value print(Number(20) > Number(3)) print(Number(1) < Number(5)) print(Number(15) >= Number(15)) print(Number(10) <= Number(2))
該代碼使用total_ordering裝飾器用于簡化為類實現(xiàn)實例排序的過程。只需要定義__lt__和__eq__。
3. 在一個類中定義多個構(gòu)造函數(shù)
函數(shù)重載是編程語言中非常常見的功能。即使Python不能重載正常的函數(shù),我們也可以使用類方法重載構(gòu)造函數(shù):
import datetime class Date: def __init__(self, year, month, day): self.year = year self.month = month self.day = day @classmethod def today(cls): t = datetime.datetime.now() return cls(t.year, t.month, t.day) d = Date.today() print(f"{d.day}/{d.month}/{d.year}")
# 14/9/2019
可以不使用構(gòu)造函數(shù)將所有邏輯都放入__init__并使用*args,**kwargs和一堆if語句來解決,但是比較丑陋,沒有可讀性和可維護性。
4. 獲取對象信息
Python提供了幾個函數(shù)以便我們更好的獲取對象的信息,這些函數(shù)包括:type、isinstance和dir。
其中type():用于判斷對象類型:
>>> type(None) <class 'NoneType'> >>> type(abs) <class 'builtin_function_or_method'>
對類對象type()返回的是對應class類型。下面是判斷兩個變量的type類型是否相同:
>>> type(11) == type(22) True >>> type('abc') == str True >>> type('abc') == type(33) False
isinstance():可以顯示對象是否是某種類型
>>> class Husty(Dog): ... pass ... >>> a = Animal() >>> b = Dog() >>> c = Husty() >>> isinstance(c,Husty) True >>> isinstance(c,Dog) True >>> isinstance(c,Animal) True >>> isinstance(b,Husty) False
Husty是Husty、Dog、Animal類型的對象,卻不能說Dog是Husty的對象。
dir():用于獲取一個對象的所有方法和屬性。返回值是一個包含字符串的list:
>>> dir('abc') ['__add__', '__class__',…… '__hash__', '__init__', '__i ……'isalnum 'isidentifier', 'islower', …… 'translate', 'upper', 'zfill']
其中,類似__xx__的屬性和方法都是有特殊用途的。如果調(diào)用len()函數(shù)視圖獲取一個對象的長度,其實在len()函數(shù)內(nèi)部會自動去調(diào)用該對象的__len__()方法。
5. Iterator和切片
如果直接對Iterator切片,則會得到TypeError,指出生成器對象不可下標反問,但是有一個技巧:
import itertools s = itertools.islice(range(50), 10, 20) for val in s: ...
使用itertools.islice,可以創(chuàng)建一個islice對象,該對象是生成所需項目的迭代器。但是,這會消耗所有生成器項,直到分片開始為止,而且還會消耗islice對象中的所有項。
6. 跳過一些行
有時,必須使用已知以可變數(shù)量的不需要的行(例如注釋)。也可以使用itertools:
string_from_file = """ // Author: ... // License: ... // // Date: ... Actual content... """ import itertools for line in itertools.dropwhile(lambda line: line.startswith("//"), string_from_file.split("\n")): print(line)
該代碼段僅在初始注釋部分之后產(chǎn)生行。如果只想在迭代器的開頭丟棄并且不知道其中有多少個項目,則此方法很有用。
7. 命名切片
使用大量硬編碼的索引值會很容易引起代碼繁瑣和破壞代碼可讀性。常用的技巧是對索引值使用常量,除此之外我們可以使用命名切片:
示例中,可以看到可以索引,方法是先使用slice函數(shù)命名它們,然后在切出一部分字符串時使用它們。還可以使用切片對象的屬性.start,.stop和.step獲得更多信息。
四、調(diào)試技巧
1. 腳本調(diào)試
Python的腳本調(diào)試可以是使用pdb模塊。它可以讓我們在腳本中隨意設置設置斷點:
import pdb pdb.set_trace()
可以在腳本中任何位置指定pdb.set_trace()并設置斷點,非常便捷
2. 在shell中調(diào)試程序
在shell中,可以使用python的-i選項就可以啟動交互式環(huán)境,在該環(huán)境下可以打印運行時變量值并調(diào)用函數(shù)的操作等,比如下面的test.py腳本
def func(): return 0 / 0 func()
在shell中通過python -i test.py運行腳本
我們import pdb然后調(diào)用pdb.pm()啟動調(diào)試器
會顯示程序到崩潰的地方,我們退出程序的在該處設置一個斷點:
import pdb; def func(): pdb.set_trace() return 0 / 0 func()
再次運行它,會在斷點處停止,step到下一步
用這樣的方法,我們可以調(diào)試和回溯程序的執(zhí)行。通過設置斷點,然后在運行程序時,執(zhí)行將在斷點處停止,可以檢查程序,例如列出函數(shù)參數(shù),對表達式求值,列出變量或step逐步執(zhí)行等。
五、有用的小工具
1. 一鍵web服務共享
在Python中可以使用http.server一鍵啟用一個 HTTP 服務器,這是一個非常方便的共享工具:
python -m http.server
在默認監(jiān)聽端口為 8000 開啟一個服務器,可以自定義端口,比如8888
python -m http.server 8888
代碼自動補齊Jedi
Jedi是一個用于Python代碼自動補齊和靜態(tài)分析的庫。Jedi可以讓我們高效的敲代碼。
目前Jedi已經(jīng)提供了絕大多數(shù)的編輯器插件,包括Vim(jedi-vim),VSC,Emacs,Sublime,Atom等。
2. 美化異常輸出pretty-errors
Python默認的報錯輸出非常亂,看的人頭大,可讀性差。這時候就需要用pretty-errors這個錯誤美化工具了。
到此,關(guān)于“Python編程常用技巧有哪些”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。