10个你没有充分利用的令人惊叹的 Python 特性
off999 2025-05-14 15:48 25 浏览 0 评论
Python 的简单性和多功能性使其成为全球开发人员的最爱。每天有超过 1000 万开发者使用 Python 进行从网络开发、机器学习到网络脚本等各种开发,Python 的功能非常强大。然而,我们中的许多人可能并没有充分利用这些功能。在这篇博客中,我将介绍一些你可能没有充分利用的神奇 Python 功能。
1.Pathlib
-- 将杂乱无章的文件路径转化为流畅的面向对象操作
Python 中的 pathlib 模块提供了一种面向对象的方法来处理文件系统路径。与 os.path 等传统方法相比,它提供了一种更直观、更易读的方法来处理文件路径。
有了 pathlib,路径被视为对象,从而可以更轻松地执行连接路径、检查文件是否存在、读/写文件等操作。
from pathlib import Path
# Create a Path object
path = Path('/path/to/directory')
# Access parts of the path
print(path.name) # 'directory'
print(path.parent) # '/path/to'
print(path.suffix) # ''
# Join paths
path = Path('/path/to')
new_path = path / 'directory' / 'file.txt'
# Checking if path exits
if path.exists():
print("The file exists")
else:
print("The file does not exist")
# Reading from a file
path = Path('/path/to/file.txt')
content = path.read_text()
print(content)
# Listing Directory Contents
for file in path.iterdir():
print(file)官方文档:
https://docs.python.org/3/library/pathlib.html
2. Dataclass
-- 让 Python 来处理繁重的工作,而你则专注于数据
在 Python 3.7 中引入的 Python 数据类模块提供了一个装饰器 (@dataclass),它能为类自动生成特殊方法,如 __init__(), __repr__(), __eq__() 等。它通过减少模板代码,简化了主要用于存储数据的类的创建。
数据类减少了对以数据为中心的类中模板代码的需求,使开发人员能够专注于逻辑而不是编写多余的代码。它能自动处理初始化实例、比较对象和打印类的可读表示等常见任务。此外,数据类还支持默认值、类型提示和不变性,只需极少的工作量。
from dataclasses import dataclass
@dataclass
class Product:
name: str
price: float
quantity: int = 0
category: str = "General"
# Method to restock the product
def restock(self, amount: int) -> None:
self.quantity += amount
print(f"Restocked {amount} units of {self.name}. Total now: {self.quantity}")
# Method to sell the product
def sell(self, amount: int) -> None:
if self.quantity >= amount:
self.quantity -= amount
print(f"Sold {amount} units of {self.name}. Remaining: {self.quantity}")
else:
print(f"Not enough stock to sell {amount} units. Only {self.quantity} available.")
# Method to display product info
def display_info(self) -> None:
print(f"Product: {self.name}")
print(f"Category: {self.category}")
print(f"Price: ${self.price}")
print(f"Stock: {self.quantity} units")
# Example usage
product = Product(name="Laptop", price=999.99, quantity=5, category="Electronics")
# Restocking the product
product.restock(10)
# Selling the product
product.sell(3)
# Displaying product information
product.display_info()3.海象操作符(Walrus)
walrus 操作符 (:=) 是 Python 3.8 中引入的赋值表达式。它允许你为表达式中的变量赋值。在引入之前,赋值只允许在独立语句中进行,但 walrus 操作符允许在循环、条件和函数调用等表达式中进行赋值。
海象操作符将赋值和求值合并为一个步骤,从而减少了冗余,这在循环和条件语句中尤其有用。它提高了可读性和效率,无需单独的赋值步骤,从而减少了代码行数。此外,当需要评估和赋值一个将被多次使用的值时,它还有助于简化代码。
while True:
user_input = input("Enter a valid string (non-empty): ")
if len(user_input) > 0:
break
print(f"Valid input received: {user_input}")在上述代码中,字符串被评估了两次,一次是在读取输入时,另一次是在 if 条件中检查其长度。
我们看看改用海象操作符的效果:
while (user_input := input("Enter a valid string (non-empty): ")) and len(user_input) == 0:
print("Invalid input, try again.")
print(f"Valid input received: {user_input}")这段代码的关键部分是 user_input := input(...),其中的 := 就是“海象操作符”。它的作用是同时赋值和返回值。这意味着 user_input := input(...) 这个表达式会把 input() 的结果赋给 user_input,同时这个表达式的返回值也是 input() 的结果。所以,在 while 循环条件中,不仅仅是检查 user_input,而且还会在检查的同时给 user_input 赋值。
换句话说,这里我们通过海象操作符让代码可以在一行里完成输入和赋值,并立即对输入进行检查。
4. Getter & Setters
-- 代码的无声保护者,巧妙地保护着数据。
Getters 和 setters 是用于获取(检索)和设置(修改)类中私有属性值的方法。它们控制对对象内部状态的访问,执行规则和验证,同时保持实际数据的封装。
在 Python 中,@property 装饰器创建了一种 Pythonic 方法来实现Getters 和 Setters,而无需像普通方法那样调用它们。
- 它确保只能设置有效值,避免不必要的错误。
- 它允许你在不影响外部代码的情况下更改内部实现。
我们看下面这个例子,我希望创建一个余额永远不会为负的 BankAccount 类:
class BankAccount:
def __init__(self, balance):
self.balance = balance
account = BankAccount(100)
account.balance = -50 ## Negative Input使用上述方法可能会导致出现负的账户余额,从而破坏代码和逻辑,而使用 setters 可以确保余额始终为非负,从而提供安全性和验证。
class BankAccount:
def __init__(self, balance):
self._balance = None # private attribute
self.balance = balance # invoke setter
@property
def balance(self):
return self._balance
@balance.setter
def balance(self, value):
if value < 0:
raise ValueError("Balance cannot be negative!")
self._balance = value
# Usage
account = BankAccount(100)
print(account.balance) # 100
account.balance = -50 # Raises ValueError: Balance cannot be negative!经常使用 Getter 和 Setter 非常重要,因为让用户随意修改你的数据,就像让小孩开车一样危险!
5. Memory Slots
在 Python 中,__slots__ 特性通过限制对象的属性来减少内存的使用。通常,Python 使用动态字典 (__dict__)来存储对象的属性,这样做有一定的灵活性,但会消耗更多的内存。
想象一下,在一个每个用户只需要几个属性(姓名、电子邮件)的系统中,你要创建数百万个轻量级用户对象。减少内存使用量可以大大提高性能。
class User:
def __init__(self, name, email):
self.name = name
self.email = email
# Creating a million users without `__slots__`
users = [User(f"User{i}", f"@example.com">user{i}@example.com") for i in range(1000000)]在上述情况下,Python 为每个 User 对象分配一个内部字典(__dict__),用来存储对象的属性(即 name 和 email)。由于字典的灵活性,用户可以动态添加新的属性,比如 user1.age = 25。这种灵活性使得每个对象都维护一个独立的字典,而字典结构会占用额外的内存空间。因此当需要创建 100 万个对象时,每个对象都有自己的字典,整体内存占用会较大。对于内存敏感的应用,这可能成为一个问题。
为了解决这个问题,我们可以这样改写代码:
class User:
__slots__ = ['name', 'email'] # Declare fixed attributes
def __init__(self, name, email):
self.name = name
self.email = email
# Creating a million users with `__slots__`
users = [User(f"User{i}", f"@example.com">user{i}@example.com") for i in range(1000000)]在优化后的版本中,__slots__ 明确指定了类的属性为 name 和 email,这样 Python 不会为每个对象创建 __dict__,而是直接为每个对象分配固定的内存块来存储这些属性。这种方式省去了字典开销,内存占用显著减少。这在需要创建大量对象时可以节省大量内存。
6. functools.lru_cache
在 Python 中,functools.lru_cache 是一个装饰器,它为函数添加了一种简单但有效的缓存机制。缓存(Memoization)是一种通过存储耗时函数调用的结果,并在相同输入再次出现时返回缓存结果的技术,用于加速程序执行。
对于计算量大或经常调用相同参数的函数,这可以大大提高性能。
from functools import lru_cache
@lru_cache(maxsize=None) # maxsize=None means the cache can grow indefinitely
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
# Calculate Fibonacci numbers
print(fibonacci(10)) # Output: 55
print(fibonacci(15)) # Output: 610示例解释:
- @lru_cache(maxsize=None) 修饰了 fibonacci 函数,使缓存大小不受限制(maxsize=None)。
- fibonacci 函数以递归方式计算斐波那契数字,但通过将结果存储在缓存中避免了冗余计算。
如果不进行内存化,递归计算斐波那契数的效率会因重复计算而降低。使用 lru_cache 进行记忆化可以存储之前计算的结果,减少冗余计算,显著提高性能。
7. Callable
在 Python 中,__call__ 是一种特殊的方法,它允许类的实例像函数一样运行。在类中定义 __call__ 时,可以像函数一样调用对象本身,传递参数并接收返回值。它为对象的交互和行为方式增加了灵活性。
假设你正在为一个 API 创建一个速率限制器,需要限制函数被调用的频率。
class RateLimiter:
def __init__(self, limit):
self.limit = limit
def is_allowed(self, requests):
return requests <= self.limit
limiter = RateLimiter(100)
print(limiter.is_allowed(80)) # True没有 __call__ 时,每次都需要明确调用 is_allowed,但有了 __call__ 后,RateLimiter 实例的行为就像一个函数,使代码更简单、更整洁。
class RateLimiter:
def __init__(self, limit):
self.limit = limit
def __call__(self, requests):
return requests <= self.limit
# Now you can call the object like a function
limiter = RateLimiter(100)
print(limiter(80)) # True
print(limiter(120)) # False8. Generators & Yield
Generators 是 Python 中一种特殊的函数类型,使用 yield 关键字返回迭代器。Generators 不会一次性返回所有结果,而是每次生成一个值,允许你按需惰性地迭代数据。这意味着它只在需要时计算值,从而节省内存和处理时间,特别是在处理大型数据集时。
假设你正在处理一个庞大的日志文件,读取每一行并筛选特定的关键字。Generators 可以在不将整个文件载入内存的情况下处理每一行。
def process_logs(filename):
logs = []
with open(filename) as file:
for line in file:
if "ERROR" in line:
logs.append(line)
return logs
# This will load all lines into memory
logs = process_logs("server.log")
for log in logs:
print(log)这种方法会将整个日志文件加载到内存中,对于大文件来说并不理想。可以使用Generators改写:
def process_logs(filename):
with open(filename) as file:
for line in file:
if "ERROR" in line:
yield line
# Using a generator to process logs lazily
for log in process_logs("server.log"):
print(log)9. Suppress
Suppress 是一个 Python 上下文管理器,你可以使用它选择性地忽略某些错误,而不是用多个 try-except 块来封装您的代码。如果你知道某些异常是可以忽略的,那么它就能提供更简洁、更易读的代码。
举个例子,在进行文件操作时,文件可能不存在,但这对程序并不重要。与其抛出错误或明确捕获错误,不如简单地抑制错误并继续前进。
使用try-except:
try:
os.remove("non_existent_file.txt")
except FileNotFoundError:
pass改用Suppress:
from contextlib import suppress
import os
# Suppress the FileNotFoundError if the file doesn't exist
with suppress(FileNotFoundError):
os.remove("non_existent_file.txt")Suppress上下文管理器可以优雅地处理异常,而不需要显式异常处理,从而使代码更加简洁。
10.MappingProxy
MappingProxyType 是 Python 字典的不可变封装。它允许对字典进行只读访问,同时防止修改原始数据。这在需要保护数据但又希望数据可读时特别有用。
假设你正在管理一个系统的配置字典。多个组件都需要读取配置,但任何人都不能在配置设置后对其进行修改。如果使用普通字典:
config = {"debug": True, "version": "1.0"}
# Anyone can modify the configuration
config["version"] = "2.0"在这种情况下,任何可以访问配置字典的人都可以更改它。而 MappingProxyType 可以将配置字典封装为只读版本,确保任何人都无法在创建后更改它。
from types import MappingProxyType
config = {"debug": True, "version": "1.0"}
# Create a read-only view of the dictionary
read_only_config = MappingProxyType(config)
# Attempt to modify will raise a TypeError
try:
read_only_config["version"] = "2.0"
except TypeError:
print("Cannot modify a read-only dictionary.")
# You can still access values
print(read_only_config["version"]) # 1.0相关推荐
- 电脑装不了系统是什么原因(为什么我电脑装不了系统)
-
电脑不能安装新系统的原因可能有多种。可能是由于硬件不兼容,例如新系统需要更高的处理器或内存要求,而电脑的配置不足。另外,可能是由于硬盘空间不足或损坏,导致无法安装新系统。还有可能是由于操作系统安装文件...
- win7忘记开机密码u盘启动(windows7忘记开机密码用u盘)
-
win7电脑忘记开机密码,之后可以通过PE的方式来进行启动。首先需要找一块U盘,然后再网上下载一个PE系统。把这块U盘做成PE系统启动盘,然后把电脑设置成U盘启动,这样就直接可以进入到系统,进去之后就...
- 开不了机的手机怎么处理(开不了机的手机怎么处理掉)
-
方法/步骤手机突然开不了机,先长按开机键,因为有的时候,现在的知道手机,突然关机了,系统一下子在死机状态,等你长了后,手机就会有一下振动的声音,你再放开手,再重新按开机键,就能开机了。如果长按还是开不...
- cdlinux手机版(cdlinux最新版0.9.8)
-
Kali更好。1.首先,Kali是专门为渗透测试和网络安全而设计的操作系统,它拥有广泛的渗透测试工具和资源,使得用户在这个领域有更多的选择和更强大的功能。2.其次,Kali具有更长的发展历史和更大...
- 电脑cpu处理器排名天梯图(电脑cpu处理器天梯榜)
-
1.荣耀王者段位:A15处理器(5核GPU版)、A15处理器(4核GPU版)不论是从跑分上还是具体体验上,苹果最新的A15处理器都是佼佼者,CPU和GPU大幅领先于安卓现役旗舰SOC2.王者段位:骁龙...
- 电脑怎么重装系统不删除文件
-
一般应用程序的目录你删了只影响程序本身,比如你把某雷的download目录删掉,那只是曾经下载在这个目录下的文件被删了,对电脑应用毫无影响,如果你删除程序的安装目录,那程序就跪了…如果你删除操作系统的...
- 电脑用久了反应慢怎么处理(电脑用久了反应迟钝)
-
方法一:检查电脑配置首先,我们要检查一下自己的电脑配置是否符合安装Windows10系统的要求。如果你的电脑配置本身比较低,比如CPU、内存、硬盘等都不够强劲,那么安装Windows10系统可能会导致...
- 怎么加入已有的局域网(怎么加入已有的局域网连接)
-
你要先知道你公司局域网自己建立的名字,可以从其他的机子上看,比如mshome,workgroup,或者别的什么的。然后,你们有集线器或者路由器吧,插好网线,一边接集线器,一边接电脑网卡。把网卡驱动。...
- 如何在微软官网下载win10系统
-
从微软官网下载win10具体有以下7步:1、输入微软的官网,进入。2、登录自己的账号。3、一直往下拉,可以看到“获取win10”。4、选择要下载的版本。5、选择下载到你自己制定的文件夹,点击...
- 路由器地址怎么改(路由器地址怎么改成别的城市)
-
1、将本机电脑IP地址设置为自动获取。2、打开IE浏览器,在地址栏中输入192.168.1.1或192.168.0.1,在弹出的用户名和密码框中输入默认值,即admin/admin,如果修改过路由器使...
-
- 台式电脑怎么换显卡(台式电脑怎么换显卡视频)
-
1.准备好螺丝刀,拆箱之前我们的手先在周围找金属物品触摸下,释放静电,避免静电击坏电子元件。用螺丝刀拆下螺丝,取下盖子。2.用螺丝刀拆下锁住扩展卡的螺丝和挡片。3.双手各握住一方,用力均衡,然后慢慢地推出电脑显卡。4.之后即可成功取出电脑主...
-
2025-12-26 17:51 off999
- wifi连接上却不能访问互联网
-
原因一:路由器问题,可能路由器过热或者损坏;重启一下路由器试试,或者将路由器恢复一下出厂设置,然后重新拨号上网,并根据设置向导重新设置WiFi,或者更换新路由器再进行拨号连接上网。 原因二:可能宽带...
-
- 显卡驱动在哪里打开(显卡驱动设置在哪里)
-
1.以华硕x16、windows11、amd22.8.1为例。先进入电脑桌面,然后点击电脑开始菜单。2.找到“AMDRadeonsettings”点击展开。3.可以看到“AMDRadeonsettings”的主程序,点击打开。4.这...
-
2025-12-26 16:51 off999
- bios启动项里找不到固态硬盘
-
这个是BIOS设置问题,操作步骤不正确。需要在【启动】菜单中【硬盘BBS属性】中设置。下面提供一下完整的操作步骤,请参考:1、将装有固态硬盘的电脑重启,同时按键盘F2键。2、进入BIOS界面,在标题栏...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
python入门到脱坑 输入与输出—str()函数
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
系统u盘安装(win11系统u盘安装)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
