你一定沒讀過的8個技巧,90%的程序員都不知道


關於 Python_你一定沒讀過的8個技巧,90%的程序員都不知道

介紹 Python 功能和小技巧的文章網上有無數篇,比如變量解壓縮,partial 偏函數,枚舉可迭代對象... 但關於 Python 我們能說的還有很多。所以今天我將向大家展示一些我知道和有使用過的特性,這些特性在其它文章或博客中很少被提及:

消毒字符串輸入

對用戶輸入內容進行消毒幾乎適用於你寫的每一個程序。通常來說轉換字符大小寫的操作就足夠了,有時候用 Regex 正則表達式就能完成,但對於比較複雜的情況,我們有更好的辦法:

user_input = "This\\nstring has\\tsome whitespaces...\\r\\n"

character_map = {

ord('\\n') : ' ',

ord('\\t') : ' ',

ord('\\r') : None

}

user_input.translate(character_map) # This string has some whitespaces... "

在這個例子中我們可以看到空格子字符"\\n"和"\\t"已被單個空格代替,而"\\r"已經被刪除。這是一個很簡單的示例,但我們可以更進一步,並使用unicodedata包和它的 combining() 函數來重新生成映射。

迭代器切片

如果嘗試對 Iterator 進行切片,則會出現 TypeError和"generator object is not subscriptable"的報錯,但我們有一個簡單的解決辦法:

import itertools

s = itertools.islice(range(50), 10, 20) # <itertools.islice>

for val in s:

...

通過使用 itertools.islice我們可以創建一個 islice對象,該對象是產生所需項目的迭代器。不過這裡需要注意的是,它會消耗所有的生成器項直到切片的開始為止,而且還會消耗 islice對象中的所有項。在學習Python的過程中,往往因為沒有資料或者沒人指導從而導致自己不想學下去了,因此我特意準備了個群 592539176 ,群裡有大量的PDF書籍、教程都給大家免費使用!不管是學習到哪個階段的小夥伴都可以獲取到自己相對應的資料!

跳過可迭代對象的開始部分

有時候你不得不去處理這樣一些文件,它們的開頭是毫無用處的行,比如註釋之類的。itertools再一次地能在這裡派上用場:

string_from_file = """

// Author: ...

// License: ...

//

// Date: ...

Actual content...

"""

import itertools

for line in itertools.dropwhile(lambda line: line.startswith("//"), string_from_file.split

print(line)

這個代碼片段只會生成文件開始註釋之後的部分。如果我們只想丟棄可迭代對象開頭的某些項(比如這個例子中的註釋部分),但不確定這個項的大小,這個方法很實用。

大家想必都知道如何用 with聲明來打開文件或者獲取鎖,但我們能實現自己的 with聲明嗎?是的,實際上通過使用 enter和 exit我們就可以實現一個上下文管理器協議:

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 中實現上下文管理最常見的方法,但其實還有一種更簡單的方法:

from contextlib import contextmanager

@contextmanager

def tag(name):

print(f"")

yield

print(f"")

with tag("h1"):

print("This is Title.")

上面的代碼片段使用 contextmanager管理器裝飾器實現了內容管理協議 。進入 with塊時,執行 tag()的第一部分(在 yield之前),然後再執行該塊,最後執行 tag()剩下的部分。

slots節省內存

如果在你編寫的程序中會創建某個類的大量實例,那麼你肯定已經注意到你的程序會佔用大量內存。這是因為 Python 使用 Dictionary 來表示類實例的屬性,雖然它速度很快但內存效率卻很低。大部分情況下這個問題並不那麼嚴重,但如果它對你的程序來說是一個大問題,你可以嘗試使用

slots

class Person:

__slots__ = ["first_name", "last_name", "phone"]

def __init__(self, first_name, last_name, phone):

self.first_name = first_name

self.last_name = last_name

self.phone = phone

所以這裡的情況就是當我們定義slots的屬性時,Python 使用的是小型的固定大小的數組,而不是 dictionary,這就大大減少了每個實例所需的內存。使用 slots也有缺點——我們無法聲明任何新屬性,並且只能在 slots上使用它們。同樣,帶有 slots的類不能使用多重繼承。

限制 CPU 和內存使用

如果你不是想通過優化程序來降低它的 CPU 和內存使用率,而是想簡單粗暴地直接限制它為某個數字,那麼 Python 中有一個庫可以做到:

import signal

import resource

import os

# To Limit CPU time

def time_exceeded(signo, frame):

print("CPU exceeded...")

raise SystemExit(1)

def set_max_runtime(seconds):

# Install the signal handler and set a resource limit

soft, hard = resource.getrlimit(resource.RLIMIT_CPU)

resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard))

signal.signal(signal.SIGXCPU, time_exceeded)

# To limit memory usage

def set_max_memory(size):

soft, hard = resource.getrlimit(resource.RLIMIT_AS)

resource.setrlimit(resource.RLIMIT_AS, (size, hard))

這裡我們看到了兩種限制最大 CPU 運行時間和最大內存使用的方法。對於 CPU 限制,我們首先獲得該特定資源( RLIMIT_CPU)的軟限制與硬限制,然後使用參數指定的描述和閒錢獲取的硬限制來設置它。最後,如果 CPU 時間被超出,我們將註冊導致系統退出的信號。至於內存方面,我們再次獲取軟限制與硬限制,並使用帶有 size 參數的 setrlimit和獲取的硬限制對其進行設置。

控制可導入和不可導入的內容

有些語言對於到處成員變量,方法和接口有著非常明確的機制,比如 Golang,在 Go 中僅有以大寫字母開頭的成員才能被導出。另一方面,在 Python 中,所有內容都可以到處,除非我們使用

all

def foo():

pass

def bar():

pass

__all__ = ["bar"]

根據上面的代碼片段,我們可以看出只有 bar()會被導出。另外,我們可以將 all保留為空,並且從此模塊導入時,不會輸出任何 AttributeError。

比較運算符的簡便方法

Python 中有很多比較運算符:lt , le , gtge,但有沒有更容易的方法呢?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裝飾器用於簡化為我們的類實現實力順序的過程。只需要定義 lteq,這也是映射剩餘操作所需的最低要求,也是裝飾器的工作——它為我們填補了這個空缺。

總結

上述的特性與操作都不一定是你在日常 Python 編程中常用到的,但其中一些時不時會讓你感到頭疼。上面所提供的解決方案大多簡化了很多任務,這些任務用較為常見的方法處理都會比較冗長無聊。另外要指出的一點是,所有的這些功能都是 Python 標準庫的一部分。在我看來,其中一些功能類似於“標準庫中的非標準功能”,因此每當你想要在 Python 中實現某些功能時,首先去標準庫裡找一找,如果沒有這個功能,那肯定是你找得不夠仔細,如果實在是沒有,再去找相關的第三方庫。

Python的簡便,是最重要的學習理由了,如果你想學Python的話,小編這裡為你整理準備了一些視頻自學教程,希望對你有所幫助!

關於 Python_你一定沒讀過的8個技巧,90%的程序員都不知道


關於 Python_你一定沒讀過的8個技巧,90%的程序員都不知道

如果你需要這些java、python等編程語言的自學視頻教程的話,可以私信小編:“資料”,就可以免費領取到啦!可以的話請幫小編轉發一下,讓更多的小夥伴可以分享到這麼好的學習乾貨資料,謝謝大家!


分享到:


相關文章: