分享30个让我感到新奇的Python小知识

0 评论
/ /
632 阅读
/
30351 字
25 2023-04

分享30个让我感到新奇的Python小知识

当你学习 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

非直接翻译,有自行改编和添加部分,翻译水平有限,难免有疏漏,欢迎指正