分享30個讓我感到新奇的Python小知識

前端達人 發佈 2024-01-11T11:16:34.088864+00:00

在文章結尾,我想提醒您,文章的創作不易,如果您喜歡我的分享,請別忘了點讚和轉發,讓更多有需要的人看到。

轉載說明:原創不易,未經授權,謝絕任何形式的轉載

當你學習 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')

列印輸出的內容:

  1. 列印 '\033[1A' 字符會將我們的光標向上移動一行。
  2. 列印 '\x1b[2K' 字符會清除整個當前行。
  3. 當它們一起列印時,我們可以取消列印整行的內容。

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

非直接翻譯,有自行改編和添加部分,翻譯水平有限,難免有疏漏,歡迎指正

關鍵字: