摘要:如果你学习 Python 有一段时间了,你可能会遇到一些比较迷惑功能。它们看起来比较复杂,实际非常好用的技巧。
如果你学习 Python 有一段时间了,你可能会遇到一些比较迷惑功能。它们看起来比较复杂,实际非常好用的技巧。
这些功能都是非常出色的工具,只要你了解它们,就能让你的代码更简洁、更高效、更优雅。
我们用简单的语言分解其中的 10 个功能。
装饰器看起来像魔法。
你在函数上方添加一个@something,突然间,函数的行为就变了。这是怎么回事呢?装饰器可以让你在不修改代码的情况下修改或扩展函数或方法的行为。
将它们视为添加额外功能的一种方式。
示例:
def greet_decorator(func):def wrapper:
print("Hello!")
func
print("Goodbye!")
return wrapper
@greet_decorator
def say_name:
print("My name is Python.")
say_name
当你调用say_name时,它将被封装在装饰器的wrapper函数中。它会打印 “Hello!”,运行say_name,然后打印 “Goodbye!”。生成器使用而不是return,而且它们不会同时运行。有什么意义?
生成器只在需要时才一次生成一个项目。
这对于处理大型数据集或无限序列非常有用,而且不会占用内存。
def count_up_to(n):count = 1
while count <= n:
yield count
count += 1
for number in count_up_to(5):
print(number)
count_up_to并不是创建一个完整的数字列表,而是即时生成数字。
这就像一个神奇的水龙头,能根据你的要求倒出数字。
withopen就可以了呢?上下文管理器会自动处理设置和清理工作,防止资源泄漏,比如忘记关闭文件。
with open("example.txt", "r") as file:content = file.read
print(content)
文件被打开、读取,然后在退出 with块时自动关闭。
不再调用file.close,不再意外锁定文件。
你甚至可以使用__enter__和__exit__方法来创建自己的上下文管理器。方便管理数据库连接或网络资源。
列表推导式和它们的同类(dict、set 和生成器理解)看起来像难以理解的速记。
但综合法能让你简洁地创建集合,通常能取代多行代码。
squares = [x**2 for x in range(10) if x % 2 == 0]print(squares) # Output: [0, 4, 16, 36, 64]
这个单行本为 0 到 9 之间的偶数建立了一个正方形列表。
一旦你掌握了它们的窍门,你就会想,如果没有它们,你是怎么生活的。
它在代码中看起来就像一个侧向的笑脸。它到底在做什么?
作为表达式的一部分,海象运算符可以为变量赋值。
这可以让你的代码更简短、更易读。
numbers = [10, 20, 30, 40]if (n := len(numbers)) > 3:
print(f"Too many numbers ({n})!")
Python 是一种动态类型语言,那么我们为什么要添加类型呢?
类型提示提高了代码的可读性,并能及早发现错误。它们不会在运行时强制执行,但可以帮助列式器和集成开发环境等工具。
def greet(name: str) -> str:return f"Hello, {name}!"
print(greet("Python"))
类型提示告诉你name应该是字符串,函数返回字符串。
这就像是为未来的你(或你的队友)提供了一个指南。
元类就像是 “类中之类”。
元类可以让你控制类的创建方式。它们对于执行规则或注入行为非常有用。
class Meta(type):def __new__(cls, name, bases, dct):
if 'required_attribute' not in dct:
raise TypeError("Missing required_attribute")
return super.__new__(cls, name, bases, dct)
class MyClass(metaclass=Meta):
required_attribute = True
元类在创建时会检查required_attribute是否存在。如果不存在,就会引发错误。
这就像是类的质量控制。
8.@staticmethod和装饰器:灵活的类方法既然普通方法也能正常工作,我们为什么还需要它们呢?
这些装饰器提供了定义方法的不同方法,这些方法不需要访问实例属性(@staticmethod),也不需要使用类本身(@classmethod)。class MyClass:@staticmethod
def static_method:
return "I don’t need an instance!"
@classmethod
def class_method(cls):
return f"I work with {cls}!"
print(MyClass.static_method)
print(MyClass.class_method)
static_method不关心类或实例,而class_method可以访问它所属的类。
这对实用函数或替代构造函数很有用。
__slots__看起来限制了灵活性,这与 Python 的动态特性背道而驰。__slots__,你可以告诉 Python 为属性分配固定数量的内存,从而在大型应用程序中节省内存。class MyClass:__slots__ = ['name', 'age']
def __init__(self, name, age):
self.name = name
self.age = age
name和age属性,而且占用内存更少。
非常适合有许多对象的情况。
它们涉及的方法如__get__、__set__和__delete__,让人感觉晦涩难懂。但描述符可以让你重复使用管理属性的逻辑。可以把它们看作高级属性装饰器。
class Descriptor:def __get__(self, instance, owner):
return instance._value
def __set__(self, instance, value):
instance._value = value * 2
class MyClass:
attr = Descriptor
def __init__(self, value):
self._value = value
obj = MyClass(10)
obj.attr = 20
print(obj.attr) # Output: 40
描述符在赋值前会将数值加倍,这样就不必在多个地方重复这一逻辑。
来源:小茵论科技