轉載說明:原創不易,未經授權,謝絕任何形式的轉載
當你學習 Python 時,可能會遇到一些令人困惑的概念或語法。但是,了解一些新的、有趣的 Python 技巧可以讓你更加深入地理解這門語言。在這篇文章中,我們將探討 30 個新奇的 Python 小知識,涉及各種主題,包括函數、類、數據類型、內置函數等等。閱讀本文,相信你將收穫新的知識和技能,讓你的 Python 之旅更加有趣和富有成效。
1、映射代理(不可變字典)
映射代理是一種字典,創建後無法更改。我們使用它的原因是不希望用戶能夠更改我們的值。
from types import MappingProxyType
mp = MappingProxyType({'apple':4, 'orange':5})
print(mp)
# {'apple': 4, 'orange': 5}
如果我們試圖更改映射代理中的內容,就會出現錯誤。
from types import MappingProxyType
mp = MappingProxyType({'apple':4, 'orange':5})
print(mp)
'''
Traceback (most recent call last):
File "some/path/a.py", line 4, in <module>
mp['apple'] = 10
~~^^^^^^^^^
TypeError: 'mappingproxy' object does not support item assignment
'''
2、類和對象的 dict 不同
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
rocky = Dog('rocky', 5)
print(type(rocky.__dict__)) # <class 'dict'>
print(rocky.__dict__) # {'name': 'rocky', 'age': 5}
print(type(Dog.__dict__)) # <class 'mappingproxy'>
print(Dog.__dict__)
# {'__module__': '__main__',
# '__init__': <function Dog.__init__ at 0x108f587c0>,
# '__dict__': <attribute '__dict__' of 'Dog' objects>,
# '__weakref__': <attribute '__weakref__' of 'Dog' objects>,
# '__doc__': None}
對象的 dict 屬性是普通字典,而類的 dict 屬性是映射代理,本質上是不可變字典(無法更改)。
3、any() and all()
any([True, False, False]) # True
any([False, False, False]) # False
all([True, False, False]) # False
all([True, True, True]) # True
any() 和 all() 函數都接受可疊代對象(例如,列表)作為參數。
any() 函數返回 True,如果至少有一個元素為 True。 all() 函數只有在所有元素都為 True 時才返回 True。
4、divmod()
內置的 divmod() 函數可以同時執行 // 和 % 運算符。
quotient, remainder = divmod(27, 10)
print(quotient) # 2
print(remainder) # 7
在 divmod(27, 10) 中,27 // 10 的結果為 2,27 % 10 的結果為 7。因此,該函數返回元組 (2, 7)。
5、使用格式化字符串輕鬆查看變量
name = 'rocky'
age = 5
string = f'{name=} {age=}'
print(string)
# name='rocky' age=5
在格式化字符串中,我們可以在變量後添加 =,以使用 var_name=var_value 的語法列印它。
6、我們可以將浮點數轉換為比率(有時是奇怪的)。
print(float.as_integer_ratio(0.5)) # (1, 2)
print(float.as_integer_ratio(0.25)) # (1, 4)
print(float.as_integer_ratio(1.5)) # (3, 2)
內置的 float.as_integer_ratio() 函數允許我們將浮點數轉換為表示分數的元組。但有時它的行為可能有些奇怪。
print(float.as_integer_ratio(0.1)) # (3602879701896397, 36028797018963968)
print(float.as_integer_ratio(0.2)) # (3602879701896397, 18014398509481984)
7、使用 globals() 和 locals() 函數顯示全局和局部變量
x = 1
print(globals())
# {'__name__': '__main__', '__doc__': None, ..., 'x': 1}
內置的 globals() 函數返回一個包含所有全局變量及其值的字典。
def test():
x = 1
y = 2
print(locals())
test()
# {'x': 1, 'y': 2}
內置的 locals() 函數返回一個包含所有局部變量及其值的字典。
8、import() 函數
import numpy as np
import pandas as pd
import() 函數是導入模塊的一種常規方法。
np = __import__('numpy')
pd = __import__('pandas')
這個函數與上面的代碼塊執行的是完全相同的操作。
9、Python 中的無限大數值
a = float('inf')
b = float('-inf')
在 Python 中,我們可以定義正無窮和負無窮。正無窮大於所有其他數,而負無窮小於所有其他數。
10、我們可以使用 'pprint' 漂亮地列印內容
from pprint import pprint
d = {"A":{"apple":1, "orange":2, "pear":3},
"B":{"apple":4, "orange":5, "pear":6},
"C":{"apple":7, "orange":8, "pear":9}}
pprint(d)
11、我們可以在 Python 中列印帶顏色的輸出。
我們需要首先安裝 colorama 包。
from colorama import Fore
print(Fore.RED + "hello world")
print(Fore.BLUE + "hello world")
print(Fore.GREEN + "hello world")
12、創建字典的更快方法
d1 = {'apple':'pie', 'orange':'juice', 'pear':'cake'}
通常的創建字典的方式
d2 = dict(apple='pie', orange='juice', pear='cake')
一個更快的創建字典的方式。它與上面的代碼塊執行的是完全相同的操作,但我們只需要輸入更少的引號。
13、我們可以在 Python 中取消列印輸出的內容
CURSOR_UP = '\033[1A'
CLEAR = '\x1b[2K'
print('apple')
print('orange')
print('pear')
print((CURSOR_UP + CLEAR)*2, end='') # this unprints 2 lines
print('pineapple')
列印輸出的內容:
- 列印 '\033[1A' 字符會將我們的光標向上移動一行。
- 列印 '\x1b[2K' 字符會清除整個當前行。
- 當它們一起列印時,我們可以取消列印整行的內容。
14、對象中的私有變量並不是真正的私有
class Dog:
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
在這裡,self.__name 變量應該是私有的。我們不應該能夠從類的外部訪問它。但是實際上我們是可以訪問的。
rocky = Dog('rocky')
print(rocky.__dict__) # {'_Dog__name': 'rocky'}
我們可以使用 dict 屬性來訪問或編輯這些屬性。
15、我們可以使用 'type()' 創建類
classname = type(name, bases, dict)
- name 是表示類名稱的字符串
- bases 是一個包含父類的元組
- dict 是一個包含屬性和方法的字典
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f'Dog({self.name}, {self.age})')
普通方式創建一個 Dog 類
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f'Dog({self.name}, {self.age})')
Dog = type('Dog', (), {'__init__':__init__, 'bark':bark})
使用 type() 創建與上述相同的 Dog 類
16、我們可以使用中文字符作為變量
我們可以使用中文字符作為變量,也可以使用表情符號,以及幾乎任何 Unicode 字符。
我 = 4
你 = 5
print(我 + 你) # 9
17、Python 中的退格符
退格符 \b 可以刪除一個列印的字符。
print('abc' + '\b' + 'd') # abd
18、響鈴符號允許我們發出鈴聲
print('\a')
可以在命令行窗口中嘗試這個。列印響鈴符號 '\a' 應該會發出鈴聲。
19、我們可以使用類作為裝飾器
class add():
def __init__(self, char):
self.char = char
def __call__(self, function):
def inner(*args):
return function(*args) + self.char
return inner
@add("!")
def greet(name):
return "hello " + name
print(greet("tom")) # hello tom!
這是由 call 魔法方法實現的,它定義了當我們調用 add 對象時發生的操作。
20、函數可以擁有變量
def test():
print('test')
test.apple = 4
print(test.apple) # 4
21、對齊字符串的簡單方法
可以使用字符串方法 ljust、rjust 和 center 分別將字符串填充空格並將字符串向左/右/中心對齊。
print('>' + 'hello'.ljust(10) + '<') # >hello <
print('>' + 'hello'.rjust(10) + '<') # > hello<
print('>' + 'hello'.center(10) + '<') # > hello <
或者我們可以使用格式化字符串來實現:
print(f'>{"hello":<10}<') # >hello <
print(f'>{"hello":>10}<') # > hello<
print(f'>{"hello":^10}<') # > hello <
22、當我們將一個列表加上它本身時會發生什麼
lis = ['apple', 'orange']
lis.append(lis)
print(lis)
# ['apple', 'orange', [...]]
23、我們可以使用 eval() 在字符串中運行 Python 代碼
print(eval('4+5')) # 9
print(eval('7-3')) # 4
eval() 是內置函數,我們不需要導入它。
24、round() 函數可以接受負數小數位數
print(round(3.14159265, 2)) # 3.14
使用 round() 的通常方法。在這裡,我們將 3.14159265 四捨五入到小數點後 2 位,因此得到 3.14。
print(round(12345, -1)) # 12340
print(round(12345, -2)) # 12300
print(round(12345, -3)) # 12000
我們還可以使用 round() 函數將數字四捨五入到最接近的 10、100、1000 等整數。
25、Python 中的海象運算符 :=
n = 5
if n > 3:
print('n is more than 3')
一個簡單的 for 循環
if (n := 5) > 3:
print('n is more than 3')
使用海象運算符 := 執行與上面相同的操作
在這裡,海象運算符與我們的賦值運算符 = 做的事情相同。但是,它還有一個額外的功能——它還返回該值本身。因此,我們可以使用這個運算符來節省一行代碼。
注意——這個功能適用於 Python 3.8+
26、我們可以將多個對象 pickling 到同一個文件中
內置的 pickle 模塊允許我們將 Python 數據結構或對象保存到二進位文件中。我們可以將多個對象保存在同一個文件中。
a = [1,2,3]
b = [4,5,6]
c = [7,8,9]
import pickle
with open('test.pckl', 'wb') as f:
pickle.dump(a, f) # saving a into test.pckl (a is the 1st object)
pickle.dump(b, f) # saving b into test.pckl (b is the 2nd object)
pickle.dump(c, f) # saving c into test.pckl (c is the 3rd object)
# Unpickling (reading) them from test.pckl
import pickle
with open('test.pckl', 'rb') as f:
a = pickle.load(f) # a = [1,2,3]
b = pickle.load(f) # b = [4,5,6]
c = pickle.load(f) # c = [7,8,9]
27、-O 標誌可以忽略 assert 語句
# this is run.py
assert 1==2
print('hello')
如果我們正常運行這段代碼,將會收到一個 AssertionError 錯誤。這是因為我們嘗試斷言 1==2,而這個表達式的結果為 False。
我們可以通過添加 -O 標誌來強制忽略所有 assert 語句。
python -O run.py
28、使用 dict.fromkeys() 創建字典
fruits = ['apple', 'orange', 'pear']
d = dict.fromkeys(fruits)
# d = {'apple':None, 'orange':None, 'pear':None}
我們可以使用 dict.fromkeys() 快速從列表創建字典。請注意,所有的值都將為 None。如果我們想要定義默認值,可以將另一個參數傳遞到 dict.fromkeys() 函數中。
fruits = ['apple', 'orange', 'pear']
d = dict.fromkeys(fruits, 100)
# d = {'apple':100, 'orange':100, 'pear':100}
29、凍結集合(frozensets)
凍結集合本質上是不可變的集合——在創建後無法進行任何更改的集合。
fs = frozenset({1, 2, 3})
為什麼我們要使用凍結集合:
- 我們可以將凍結集合添加到其他集合中(使用集合無法做到這一點)
- 我們可以使用凍結集合作為字典鍵(使用集合無法做到這一點)
- 檢查某個元素是否存在於凍結集合中仍然只需要 O(1) 的時間
30、我們可以使用 slots 強制類僅接受特定的屬性
class Dog:
__slots__ = ['name', 'age']
本質上,這是定義了 Dog 類僅能接受 name 和 age 屬性,而不能接受任何其他屬性。
dog = Dog()
dog.name = 'rocky' # no problem
dog.age = 5 # no problem
dog.breed = "german shepherd" # ERROR
我們可以為 Dog 設置 name 和 age 屬性,但不能設置其他屬性。
結論
希望您在閱讀本文後至少學到了一件有關 Python 的新知識。我們下次再見,這個列表還會變得更長。
無論是初學者還是有經驗的 Python 開發者,學習新的技巧和知識都是必要的。希望在這篇文章中,我們介紹的這些 Python 技巧能夠幫助你更加深入地了解 Python,提高你的編程技能,讓你的代碼更加簡潔和高效。Python 語言的靈活性和易用性是它如此受歡迎的原因之一。希望你能夠不斷探索和學習 Python,創造出令人驚嘆的項目和應用。
在文章結尾,我想提醒您,文章的創作不易,如果您喜歡我的分享,請別忘了點讚和轉發,讓更多有需要的人看到。同時,如果您想獲取更多前端技術的知識,歡迎關注我,您的支持將是我分享最大的動力。我會持續輸出更多內容,敬請期待。
原文:https://python.plainenglish.io/30-things-i-never-knew-about-python-until-recently-compilation-101b0817eeca
作者:Liu Zuo Lin
非直接翻譯,有自行改編和添加部分,翻譯水平有限,難免有疏漏,歡迎指正