您现在的位置是:首页 >技术交流 >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 多平台发布