发布于 2026-01-06 2 阅读
0

你可能不知道的 6 个 Python 语言实用特性:数据类、任意高级切片运算符、参数解包、Functools、双下划线/魔术方法

你可能不知道的 6 个实用 Python 语言特性

数据类

任何及所有

高级切片操作员

论点剖析

函数工具

邓德/魔法方法

Python 编程语言的优势之一在于,它既易于初学者学习,同时又能为高级用户带来巨大的回报。

数据类

数据类是专门用作数据容器的类。它们通常不包含任何业务逻辑。

Python 提供了一个@dataclass装饰器,添加到类中后,它会自动生成几个有用的方法,这样你就无需手动编写它们。这些方法包括__init__生成构造函数的方法、__str__生成__repr__字符串表示的方法以及__eq__检查类实例是否相等的方法。

定义数据类很简单。

@dataclass()
class Article:
    title: str
    author: str
    published_on: datetime
    views: int
    likes: int
Enter fullscreen mode Exit fullscreen mode

您还可以选择为变量设置默认值。

@dataclass()
class Article:
    title: str = "John Doe"
    author: str = "Unknown"
    published_on: datetime = datetime.now()
    views: int = 0
    likes: int = 0
Enter fullscreen mode Exit fullscreen mode

如需查看自动生成方法的完整列表,您可以查阅官方文档

任何及所有

有时,在执行某个操作之前,例如在语句中,需要检查多个条件if。Python 提供了布尔and运算or符来评估此类逻辑表达式。但是,当条件数量非常多时,语句可能会变得相当冗长笨拙。

` any()and`all()方法只是更简洁、更易读地一次性评估大量布尔表达式的方法。`is`any()等价于一系列or操作,而all()`is` 等价于一系列and操作。

假设你得到一份某学生的成绩清单……

marks = [67, 85, 48, ]
passing_marks = 33
Enter fullscreen mode Exit fullscreen mode

……你想检查该学生是否符合升入下一年级的资格。一种方法是将每次比较结果与and运算符连接起来:

if marks[0] > passing_marks and marks[1] > passing_marks and marks[2] > passing_marks:
    promoted = True
else:
    promoted = False
Enter fullscreen mode Exit fullscreen mode

您可以使用以下all()函数使这段代码更易于阅读:

if all([marks[0] > passing_marks, marks[1] > passing_marks, marks[2] > passing_marks]):
    promoted = True
else:
    promoted = False
Enter fullscreen mode Exit fullscreen mode

最后,你可以将它与列表推导式结合起来,得到一个简洁明了的解决方案:

if all([subject_marks > passing_marks for subject_marks in marks]):
    promoted = True
else:
    promoted = False
Enter fullscreen mode Exit fullscreen mode

这两个功能与运算符结合使用,可以进一步扩展其功能not

以下是对这些方法的简要概述。

  • any()返回:True如果至少一个参数的值为 True。
  • all()返回True所有参数都为 True 的情况
  • not any()True如果所有参数都不为 True,则返回 true。
  • not all()True如果至少一个参数的值为 False,则返回 true。

高级切片操作员

切片运算符通常用于访问列表或字符串的特定部分。

string = "Python is awesome!"
string[3] # 'h'
string[4:7] # 'on '
Enter fullscreen mode Exit fullscreen mode

它还有许多更高级的用法。例如,可以使用负索引从末尾而不是开头进行切片。

string[-2] # 'e'
Enter fullscreen mode Exit fullscreen mode

您还可以指定“步长”来跳过切片时一定数量的元素。

string[2:9:2] # 'to s'
Enter fullscreen mode Exit fullscreen mode

步长值可以为负数。这将导致列表/字符串按相反顺序切片。

string[9:2:-2] # ' inh'
Enter fullscreen mode Exit fullscreen mode

反转数组或列表的常用快捷方法是使用切片[::-1]

string[::-1] # '!emosewa si nohtyP'
Enter fullscreen mode Exit fullscreen mode

论点剖析

***是特殊运算符,允许将多个项目打包到(或从)单个变量中解包。

你可能在函数定义中见过 `and`*args和 ` **kwargspresent` 这两个词。当出现在函数定义中时,`and` 运算*符将多个参数合并成一个元组,而 ` **present` 运算符将多个关键字参数合并成一个字典。

def product(*args):
    res = 1
    for arg in args:
        res *= arg
    return res

product(3, 4, 5)


def print_dict(**kwargs):
    for key in kwargs:
        print(f"{key}: {kwargs[key]}")

print_dict(firstname="Bikramjeet", lastname="Singh")
Enter fullscreen mode Exit fullscreen mode

另一方面,当出现在函数调用的上下文中时,它们的作用正好相反——*运算符将列表/元组的内容展开为单独的参数,而**运算符将字典的内容展开为单独的关键字参数。

list_of_nums = [3, 4, 5]
product(*list_of_nums)


d = {"firstname": "Bikramjeet", "lastname": "Singh"}
print_dict(**d)
Enter fullscreen mode Exit fullscreen mode

对于参数数量较多的函数,通常最好先将它们收集到一个字典中,然后再传递给函数。

def my_function(arg1, arg2, arg3, arg4 ... ):
    ...

params = {'arg1': ...}
my_function(**params)
Enter fullscreen mode Exit fullscreen mode

这些运算符的另一个用途是组合列表和字典。

combined_list = [*l1, *l2]
combined_dict = {**d1, **d2}
Enter fullscreen mode Exit fullscreen mode

函数工具

Python 支持高阶函数——即可以接受其他函数并返回其他函数的函数。高阶函数的概念是 Python 其他几个特性(例如装饰器)的核心。

functools包提供了一些用于处理高阶函数实用辅助函数。让我们来看其中的一些。

部分的

在某些情况下,您可能需要创建现有通用函数的“特化”版本。这可以通过“冻结”某些基本函数参数的值来实现。

考虑一个简单的函数,用于计算一个数的n次方:

def pow(base, exp):
    res = 1
    for i in range(exp):
        res *= base
    return res

pow(2, 3) # returns 8
Enter fullscreen mode Exit fullscreen mode

平方运算非常常见,因此值得专门为此创建一个函数,这样我们就无需每次都传递 2 作为参数。然而,与其重写现有pow函数,我们可以直接在方法中复用它functools.partial

square = functools.partial(pow, exp=2)
square(4) # returns 16, equivalent to pow(4, 2)
Enter fullscreen mode Exit fullscreen mode

类似地,我们也可以创建一个立方体函数:

cube = functools.partial(pow, exp=3)
cube(5) # returns 125, equivalent to pow(5, 3)
Enter fullscreen mode Exit fullscreen mode

缓存属性

这是一个装饰器,允许你缓存一些可能耗时较长的方法的返回值。例如,数据库调用通常是耗时较长的操作,因此,如果你预计它们的值不会经常变化,那么缓存它们是很有必要的。

@functools.cached_property
def my_expensive_method():
    ...
    return result
Enter fullscreen mode Exit fullscreen mode

该方法首次调用时会执行完整计算,并将返回值缓存起来。下次调用同一方法时,可以直接从缓存中获取结果。

请注意,该cached_property装饰器仅适用于 Python 3.8 及更高版本。对于较低版本的 Python,可以使用单独的软件包

总订单

当您定义自定义类时,特别是当定义一个用于存储某种数值数据的容器时,定义比较方法__eq__(等于)、__gt__(大于)、__ge__(大于等于)、__lt__(小于)和(__le__小于等于)会很有帮助,这样可以更轻松地比较这些类的对象。

class Distance:
    km: int # Kilometers
    m: int # Meters

    def __init__(self, km, m):
        self.km = km
        self.m = m

    def __eq__(self, other):
        return self.km == other.km and self.m == other.m

    def __gt__(self, other):
        if self.km > other.km:
            return True
        elif self.km < other.km:
            return False
        elif self.m > other.m:
            return True
        else:
            return False
Enter fullscreen mode Exit fullscreen mode

然而,定义所有这些方法可能很繁琐,并且会导致大量的样板代码,尤其是有 5 个方法的情况下。幸运的是,您不必这样做!给定 `a` 和 `b` ` c` 或__eq__`d` 中的任意一个的逻辑,所有其他比较方法都可以推导出来。__gt____ge____lt____le__

例如,在上面的例子中,该__le__方法可以推导如下:

def __le__(self, other):
    return not self > other
Enter fullscreen mode Exit fullscreen mode

这就是@total_ordering装饰器的作用。当它应用于至少定义了一个__eq__比较方法(包括另一个比较方法)的类时,它会自动派生出所有其他比较方法。

@functools.total_ordering
class Distance:
    ...
Enter fullscreen mode Exit fullscreen mode

邓德/魔法方法

双下划线方法是一种特殊方法,它允许你在自定义类中使用 Python 的内置运算符和关键字,例如+`& `、 *`&` len、`&` 等。这对于使代码更简洁、更易读非常有用。你可以在我之前的文章中了解更多关于双下划线方法的信息,点击此处阅读。

图片来自PixabayPaul Brennan。

文章来源:https://dev.to/bikramjeetsingh/6-nifty-python-language-features-you-might-not-know-about-6mi