您现在的位置是:首页 >技术交流 >5个令人惊叹的Python隐藏功能—第1部分网站首页技术交流
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 多平台发布





U8W/U8W-Mini使用与常见问题解决
QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结