您好,登錄后才能下訂單哦!
這篇文章主要講解了“有哪些Python小技巧”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“有哪些Python小技巧”吧!
集合
開發人員常常忘記 Python 也有集合數據類型,大家都喜歡使用列表處理一切。
集合(set)是什么?簡單來說就是:集合是一組無序事物的匯集,不包含重復元素。
如果你熟練掌握集合及其邏輯,那么很多問題都可以迎刃而解。舉個例子,如何獲取一個單詞中出現的字母?
myword = "NanananaBatman" set(myword) {'N', 'm', 'n', 'B', 'a', 't'}
就這么簡單,問題解決了,這個例子就來自 Python 的官方文檔,大可不必過于驚訝。
再舉一個例子,如何獲取一個列表的各個元素,且不重復?
# first you can easily change set to list and other way around mylist = ["a", "b", "c","c"] # let's make a set out of it myset = set(mylist) # myset will be: {'a', 'b', 'c'} # and, it's already iterable so you can do: for element in myset: print(element) # but you can also convert it to list again: mynewlist = list(myset) # and mynewlist will be: ['a', 'b', 'c']
我們可以看到,“c”元素不再重復出現了。只有一個地方你需要注意,mylist 與 mynewlist 之間的元素順序可能會有所不同:
mylist = ["c", "c", "a","b"] mynewlist = list(set(mylist)) # mynewlist is: ['a', 'b', 'c']
可以看出,兩個列表的元素順序不同。
下面,我們來進一步深入。
假設某些實體之間有一對多的關系,舉個更加具體的例子:用戶與權限。通常,一個用戶可以擁有多個權限。現在假設某人想要修改多個權限,即同時添加和刪除某些權限,應當如何解決這個問題?
# this is the set of permissions before change; original_permission_set = {"is_admin","can_post_entry", "can_edit_entry", "can_view_settings"} # this is new set of permissions; new_permission_set = {"can_edit_settings","is_member", "can_view_entry", "can_edit_entry"} # now permissions to add will be: new_permission_set.difference(original_permission_set) # which will result: {'can_edit_settings', 'can_view_entry', 'is_member'} # As you can see can_edit_entry is in both sets; so we do notneed # to worry about handling it # now permissions to remove will be: original_permission_set.difference(new_permission_set) # which will result: {'is_admin', 'can_view_settings', 'can_post_entry'} # and basically it's also true; we switched admin to member, andadd # more permission on settings; and removed the post_entrypermission
總的來說,不要害怕使用集合,它們能幫助你解決很多問題,更多詳情,請參考 Python 官方文檔。
日歷
當開發與日期和時間有關的功能時,有些信息可能非常重要,比如某一年的這個月有多少天。這個問題看似簡單,但是我相信日期和時間是一個非常有難度的話題,而且我覺得日歷的實現問題非常多,簡直就是噩夢,因為你需要考慮大量的極端情況。
那么,究竟如何才能找出某個月有多少天呢?
import calendar calendar.monthrange(2020, 12) # will result: (1, 31) # BUT! you need to be careful here, why? Let's read thedocumentation: help(calendar.monthrange) # Help on function monthrange in module calendar: # monthrange(year, month) # Return weekday (0-6~ Mon-Sun) and number of days (28-31) for # year, month. # As you can see the first value returned in tuple is a weekday, # not the number of the first day for a given month; let's try # to get the same for 2021 calendar.monthrange(2021, 12) (2, 31) # So this basically means that the first day of December 2021 isWed # and the last day of December 2021 is 31 (which is obvious,cause # December always has 31 days) # let's play with February calendar.monthrange(2021, 2) (0, 28) calendar.monthrange(2022, 2) (1, 28) calendar.monthrange(2023, 2) (2, 28) calendar.monthrange(2024, 2) (3, 29) calendar.monthrange(2025, 2) (5, 28) # as you can see it handled nicely the leap year;
某個月的第一天當然非常簡單,就是 1 號。但是,“某個月的第一天是周X”,如何使用這條信息呢?你可以很容易地查到某一天是周幾:
calendar.monthrange(2024, 2) (3, 29) # means that February 2024 starts on Thursday # let's define simple helper: weekdays = ["Monday", "Tuesday","Wednesday", "Thursday", "Friday","Saturday", "Sunday"] # now we can do something like: weekdays[3] # will result in: 'Thursday' # now simple math to tell what day is 15th of February 2020: offset = 3 # it's thefirst value from monthrange for day in range(1, 29): print(day,weekdays[(day + offset - 1) % 7]) 1 Thursday 2 Friday 3 Saturday 4 Sunday ... 18 Sunday 19 Monday 20 Tuesday 21 Wednesday 22 Thursday 23 Friday 24 Saturday ... 28 Wednesday 29 Thursday # which basically makes sense;
也許這段代碼不適合直接用于生產,因為你可以使用 datetime 更容易地查找星期:
from datetime import datetime mydate = datetime(2024, 2, 15) datetime.weekday(mydate) # will result: 3 # or: datetime.strftime(mydate, "%A") 'Thursday'
總的來說,日歷模塊有很多有意思的地方,值得慢慢學習:
# checking if year is leap: calendar.isleap(2021) #False calendar.isleap(2024) #True # or checking how many days will be leap days for given yearspan: calendar.leapdays(2021, 2026) # 1 calendar.leapdays(2020, 2026) # 2 # read the help here, as range is: [y1, y2), meaning that second # year is not included; calendar.leapdays(2020, 2024) # 1
枚舉有第二個參數
是的,枚舉有第二個參數,可能很多有經驗的開發人員都不知道。下面我們來看一個例子:
mylist = ['a', 'b', 'd', 'c', 'g', 'e'] for i, item in enumerate(mylist): print(i, item) # Will give: 0 a 1 b 2 d 3 c 4 g 5 e # but, you can add a start for enumeration: for i, item in enumerate(mylist, 16): print(i, item) # and now you will get: 16 a 17 b 18 d 19 c 20 g 21 e
第二個參數可以指定枚舉開始的地方,比如上述代碼中的 enumerate(mylist,16)。如果你需要處理偏移量,則可以考慮這個參數。
if-else 邏輯
你經常需要根據不同的條件,處理不同的邏輯,經驗不足的開發人員可能會編寫出類似下面的代碼:
OPEN = 1 IN_PROGRESS = 2 CLOSED = 3 def handle_open_status(): print('Handling openstatus') def handle_in_progress_status(): print('Handling inprogress status') def handle_closed_status(): print('Handling closedstatus') def handle_status_change(status): if status == OPEN: handle_open_status() elif status ==IN_PROGRESS: handle_in_progress_status() elif status == CLOSED: handle_closed_status() handle_status_change(1) #Handling open status handle_status_change(2) #Handling in progress status handle_status_change(3) #Handling closed status
雖然這段代碼看上去也沒有那么糟,但是如果有 20 多個條件呢?
那么,究竟應該怎樣處理呢?
from enum import IntEnum class StatusE(IntEnum): OPEN = 1 IN_PROGRESS = 2 CLOSED = 3 def handle_open_status(): print('Handling openstatus') def handle_in_progress_status(): print('Handling inprogress status') def handle_closed_status(): print('Handling closedstatus') handlers = { StatusE.OPEN.value:handle_open_status, StatusE.IN_PROGRESS.value: handle_in_progress_status, StatusE.CLOSED.value:handle_closed_status } def handle_status_change(status): if status not inhandlers: raiseException(f'No handler found for status: {status}') handler =handlers[status] handler() handle_status_change(StatusE.OPEN.value) # Handling open status handle_status_change(StatusE.IN_PROGRESS.value) # Handling in progress status handle_status_change(StatusE.CLOSED.value) # Handling closed status handle_status_change(4) #Will raise the exception
在 Python 中這種模式很常見,它可以讓代碼看起來更加整潔,尤其是當方法非常龐大,而且需要處理大量條件時。
enum 模塊
enum 模塊提供了一系列處理枚舉的工具函數,最有意思的是 Enum 和 IntEnum。我們來看個例子:
from enum import Enum, IntEnum, Flag, IntFlag class MyEnum(Enum): FIRST ="first" SECOND ="second" THIRD ="third" class MyIntEnum(IntEnum): ONE = 1 TWO = 2 THREE = 3 # Now we can do things like: MyEnum.FIRST #<MyEnum.FIRST: 'first'> # it has value and name attributes, which are handy: MyEnum.FIRST.value #'first' MyEnum.FIRST.name #'FIRST' # additionally we can do things like: MyEnum('first') #<MyEnum.FIRST: 'first'>, get enum by value MyEnum['FIRST'] #<MyEnum.FIRST: 'first'>, get enum by name
使用 IntEnum 編寫的代碼也差不多,但是有幾個不同之處:
MyEnum.FIRST == "first" # False # but MyIntEnum.ONE == 1 # True # to make first example to work: MyEnum.FIRST.value == "first" # True
在中等規模的代碼庫中,enum 模塊在管理常量方面可以提供很大的幫助。
enum 的本地化可能有點棘手,但也可以實現,我用django快速演示一下: from enum import Enum from django.utils.translation import gettext_lazy as _ class MyEnum(Enum): FIRST ="first" SECOND ="second" THIRD ="third" @classmethod def choices(cls): return [ (cls.FIRST.value, _('first')), (cls.SECOND.value, _('second')), (cls.THIRD.value, _('third')) ] # And later in eg. model definiton: some_field = models.CharField(max_length=10,choices=MyEnum.choices())
iPython
iPython 就是交互式 Python,它是一個交互式的命令行 shell,有點像 Python 解釋器。
首先,你需要安裝 iPython:
pip install ipython
接下來,你只需要在輸入命令的時候,將 Python 換成 ipython:
# you should see something like this after you start: Python 3.8.5 (default, Jul 28 2020, 12:59:40) Type 'copyright', 'credits' or 'license' for more information IPython 7.18.1 -- An enhanced Interactive Python. Type '?' forhelp. In [1]:
ipython 支持很多系統命令,比如 ls 或 cat,tab 鍵可以顯示提示,而且你還可以使用上下鍵查找前面用過的命令。
感謝各位的閱讀,以上就是“有哪些Python小技巧”的內容了,經過本文的學習后,相信大家對有哪些Python小技巧這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。