5个令人惊叹的Python隐藏功能—第1部分

Python是一个非常棒的编程语言,正如GitHub发现的那样,它也是2022年第二最受欢迎的语言。

Python最吸引人的优点是其强大的社区,似乎Python对任何使用案例都有一个软件包。

Python有许多很酷的功能,这些功能并不是公开知识

5个令人惊叹的Python隐藏功能—第1部分

通过这些酷炫的隐藏Python功能将您的编码技能提高到一个新水平

在广阔而动态的Python编程世界中,存在一组独特的功能,初学者经常会忽略,但它们在语言生态系统中提供了重要的作用。这

些是魔法方法(也称为dunder函数)

魔法方法是Python中预定义的一组方法,提供特殊的语法功能。它们可以很容易地通过开头和结尾的双下划线来识别,例如:

__init__、__call__、__len__等。

魔法方法在定义自定义对象与各种Python操作的行为方面发挥着至关重要的作用。

从本质上讲,它们允许自定义对象的行为类似于Python的内置类型。这里的直接好处是增强了Python的一致性和直观性。

在这篇文章中,我们将重点讨论强大的dunder函数背后的魔力。我们将探讨它们的目的和用法。

无论您是Python初学者还是经验丰富的程序员,本指南旨在全面理解Dunder函数,使您的Python编码体验更高效和愉快。

请记住,Python的魔力不仅在于其简单性和通用性,也在于其强大的功能,比如Dunder函数。所以,让我们一起揭开魔法的面纱!

__init__

也许所有dunder函数中最基本的就是__init__

这是Python在我们创建(或者象名字所暗示的那样初始化)新对象时自动调用的魔法方法。

class Pizza:
    def __init__(self, size, toppings):
        self.size = size
        self.toppings = toppings

# 现在让我们创建一个pizza
my_pizza = Pizza('large', ['pepperoni''mushrooms'])  

print(my_pizza.size)  
# 这将打印:大号  
print(my_pizza.toppings) 
# 这将打印:['pepperoni', 'mushrooms']

我们创建一个名为Pizza的类。将__init__函数设置为在初始化时接受我们指定的大小和配料参数,并将其设置为我们自定义对象的属性。

这里,self用于表示类的实例。所以当我们说self.size = size时,我们的意思是:“嘿,这个pizza对象有一个大小属性,我想让它是我在创建对象时提供的任何大小。”

__str____repr__

__str__

这是Python的魔法方法,允许我们为自定义对象定义一个描述。

本质上,它正在回答这个问题:"你会如何在咖啡时描述这个对象给朋友?"

当您打印一个对象或使用str()将其转换为字符串时,Python会检查您是否为该对象的类定义了

__str__

方法

如果有,它会使用该方法将对象转换为字符串。 我们可以扩展我们的Pizza示例来包括__str__函数,如下所示:

class Pizza:
    def __init__(self, size, toppings):
        self.size = size
        self.toppings = toppings

    def __str__(self):
        return f"A {self.size} pizza with {', '.join(self.toppings)}"

my_pizza = Pizza('large', ['pepperoni''mushrooms'])  
print(my_pizza)  # 这将打印:A large pizza with pepperoni, mushrooms

__repr__

__str__函数更多地以非正式的方式描述对象的属性。

另一方面,__repr__用于提供更正式、详细和无歧义的自定义对象描述。

如果在对象上调用repr(),或者只是在控制台上输入对象的名称,Python会寻找__repr__方法。 如果未定义__str__,Python会作为备选方案在试图打印对象或将其转换为字符串时使用__repr__

所以,至少定义__repr__通常是一个好主意,即使您没有定义__str__

这里是我们如何为pizza示例定义__repr__:

class Pizza:
    def __init__(self, size, toppings):
        self.size = size
        self.toppings = toppings

    def __repr__(self):
        return f"Pizza('{self.size}', {self.toppings})"

my_pizza = Pizza('large', ['pepperoni''mushrooms'])  
print(repr(my_pizza))  # 这将打印:Pizza('large', ['pepperoni', 'mushrooms'])
  

你看,__repr__给你一个字符串,你可以在Python命令中运行它来重新创建pizza对象,而__str__给你一个更人性化的描述。

希望这可以帮助你更好地理解这些dunder方法!

__add__

在Python中,我们都知道可以使用+运算符将数字相加,比如3 + 5。 但是,如果我们要添加某个自定义对象的实例呢?

__add__ dunder函数允许我们做到这一点。它给了我们定义自定义对象上+运算符行为的能力。

为了保持一致性,假设我们想为我们的pizza示例定义+行为。

我们说,每当我们将两个或更多的pizza添加在一起时,它将自动组合所有的配料。

这可能如下所示:

class Pizza:
    def __init__(self, size, toppings):
        self.size = size
        self.toppings = toppings

    def __add__(self, other):
        if not isinstance(other, Pizza):
            raise TypeError("You can only add another Pizza!")
        new_toppings = self.toppings + other.toppings
        return Pizza(self.size, new_toppings)

# 让我们创建两个pizza  
pizza1 = Pizza('large', ['pepperoni''mushrooms'])
pizza2 = Pizza('large', ['olives''pineapple'])

# 现在让我们"添加"它们  
combined_pizza = pizza1 + pizza2  

print(combined_pizza.toppings)  

# 这将打印:['pepperoni', 'mushrooms', 'olives', 'pineapple']

__add__ dunder类似,我们还可以定义其他算术函数,比如__sub__(用于使用-运算符进行减法)和__mul__(用于使用*`运算符进行乘法)。

__len__

此dunder方法允许我们定义len()函数应该为我们的自定义对象返回什么。

Python使用len()来获取列表或字符串等数据结构的长度或大小。

在我们的Pizza类的上下文中,我们可以说pizza的“长度”是它的配料数量。我们可以这样实现:

class Pizza:
    def __init__(self, size, toppings):
        self.size = size
        self. (已编辑) 

toppings = toppings
    def __len__(self):
        return len(self.toppings)
        
# 让我们创建一个pizza 
my_pizza = Pizza('large', ['pepperoni''mushrooms''olives']) 
print(len(my_pizza)) 
# 这将打印:3```

__len__方法中,我们只返回toppings列表的长度。

现在,len(my_pizza)会告诉我们my_pizza上有多少种配料。

__len__应该总是返回一个整数,并且预期是一个非负值。负值配料将很奇怪,不是吗?

__iter__

此dunder方法允许您的对象可迭代——也就是说,可以在for循环中使用。

为此,我们还需要定义__next__函数,这用于定义应该在迭代中返回下一个值的行为。

此外,它还应该在序列中没有更多项时向可迭代对象发出信号。

我们通常通过引发StopIteration异常来实现这一点。

对于我们的pizza示例,我们假设我们想迭代配料。

我们可以通过定义__iter__方法来使Pizza类可迭代, 如下所示:

class Pizza:
    def __init__(self, size, toppings):
        self.size = size
        self.toppings = toppings

    def __iter__(self):
        self.n = 0
        return self

    def __next__(self):
        if self.n < len(self.toppings):
            result = self.toppings[self.n]
            self.n += 1
            return result
        else:
            raise StopIteration



# 让我们创建一个pizza  
my_pizza = Pizza('large', ['pepperoni''mushrooms''olives'])  

# 现在让我们对其进行迭代  
for topping in my_pizza:
    print(topping)

在这种情况下,for循环调用__iter__,它初始化一个计数器(self.n)并返回pizza对象本身self

然后,for循环调用__next__以逐个获得配料。

__next__返回了所有配料后,它会引发StopIteration异常,for循环现在知道没有更多的配料,因此将停止迭代过程。

总结性评论

总之,很明显魔法方法真正位于Python语言的核心。

它们构成了Python许多内置操作的基础,给予我们开发者必要的自由度来个性化我们对象的行为,使其与语言的其余用法保持一致。

在本文中,我们讨论了如何利用诸如__init__、__iter__和__len__之类的dunder函数来满足我们的需求。

您可以在这里找到Python允许的所有dunder方法的完整列表:

本文由 mdnice 多平台发布

猜你喜欢

转载自blog.csdn.net/qq_40523298/article/details/130996171
今日推荐