资源经验分享实例讲解Python魔术方法

实例讲解Python魔术方法

2020-03-06 | |  56 |   0

原标题: 实例讲解Python魔术方法

来源:AI研习社    链接:https://www.yanxishe.com/TextTranslation/2420

使用魔术方法更改内置行为

魔术方法是一种特殊的方法,您可以定义它来将“Magic”添加到您的类中。它们总是被双下划线包围,例如,__init__u和__str__magic方法。魔术方法可以通过让我们访问Python的内置语法特性来丰富我们的类设计。

Python允许我们的类从内置类继承。内建的继承子类共享所有相同的属性,包括作为内建的方法。我们可以利用核心的内置功能,但可以通过使用魔术方法自定义选定的操作。

在本教程中,我将把这两个想法结合在一起,展示如何从内置列表类继承并在类设计中使用魔术方法。我将修改控制列表索引的三个神奇方法。通过结合这两个特性,可以构造一个非常简单易用的类,并且我们可以将行为添加到我们想要的方法中。所有Python开发人员都熟悉内置行为;反过来,这使得使用继承类变得容易学习。

最后,将演示两个更广泛的示例,说明如何在广播操作中使用魔术方法以及如何更改实例的状态。所有附带的代码都可以通过GitHub获得。

示例1:列表索引


可以操纵Magic方法来修改列表索引。类MyCustomList继承自内置列表类型。这意味着通过MyCustomList类创建的任何对象的行为都将类似于一个列表,除了我们选择有选择地自定义方法的地方。

getitem、setitem和delitem都是在访问列表索引时调用的magic方法。这些magic方法的行为可以被修改。

在下面显示的示例中,我们放弃了从第0个索引开始的列表索引的想法。如果用户试图使用第零个索引访问列表中的元素,则会引发ValueError异常,程序将终止。如果用户输入的列表索引大于1,则这些方法会将索引减少1,然后使用索引调用父类列表。

要展示如何使用MyCustomList类中定义的这些方法,请参见下面的Python交互提示。

1583478548311506.png

该示例显示如何调用getitem、setitem和delitem。可以隐式调用魔术方法。对于getitem,要访问第一个索引,只需在方括号中写下对象的名称和索引位置。

最有趣的是,当我们要求索引位置1处的元素时,返回整数值1,即使1是第0个元素。我们这里有一个从1开始索引的列表。事实上,它弥补了我们第一次学习列表索引时的困惑。

现在,让我们将列表中的整数值1更改为100。为此,我们需要调用setitem。为此,我们只需编写对象的名称,后跟方括号和赋值。同样,要更改列表中的第一个元素,我们使用索引位置1。当我们再次输出列表时,我们可以清楚地看到第一个元素已经从1变为100。

最后,从列表中删除元素可以通过__delitem__来定义。当我们使用del python关键字解析为方法调用时,将调用__delitem__魔术方法。为了进一步构建我们的列表索引示例,让我们删除索引中的第一个元素,整数值100。当我们调用del,然后是对象和要删除的元素的索引位置时,在这个例子中,列表100中的第一个元素,我们现在可以看到100实际上已经被删除了!

魔术方法提供了修改默认行为的机会。最重要的是,不需要学习新的方法名或新的接口,因此这些方法可以直观地实现。下表指定了使用MyCustomList中实现的这些魔术方法的指南。

1583478594485452.png

 如何调用magic方法getitem setitem delitem

1583478611897016.png

05.png

例2:魔法方法


我们也可以在类设计中使用乘法运算符。由于我们继承自内置列表类,因此可以将两个MyCustomList对象压缩在一起(因为它们的行为类似于列表对象),并遍历zip对象。在迭代过程中,我们可以以广播的方式将每个列表中的元素乘以另一个列表中的相应元素(请参见下面的“magic method”代码片段)。这种广播行为与Pandas和Numpy等数据分析包中的行为类似。

示例显示,我们可以使用*符号将两个MyCustomList对象组合在一起。如果在名为list_three的变量中捕获返回值并打印list_three,则会输出一个新列表。这个列表是将其他两个列表中的元素相乘的结果。

1583478665822829.png

  __mul__是MyCustomList类中的一个方法。这里,它是单独显示的。

07.png

  乘法运算符*解析为一个“mul”魔术方法调用,我们可以自定义该方法以返回所需的行为。


本例中使用的类MyCustomList的整个源代码如下所示:

1583478708789225.png

额外示例:__call__ 魔术方法

最后,我将说明如何在 Python 中调用 __call__ 魔术方法。__call__ 在需要经常更改其状态的实例的类中特别有用。“调用”实例可以是一种直观而优雅的方式来更改对象的状态。

考虑所展示的示例。  类 MyClass 具有一个初始化构造函数,该构造函数期望传递三个参数。这三个参数可以在 init 方法中传递,并在对象中指定为属性。

当我们想更改实例的状态而不实际创建新实例时,__call__ 魔术方法非常有用。  

首次初始化实例时,我传入整数 1、2 和 3 ,在实例中分别赋值给属性 var_1,var_2 和 var_3。当我使用 print 语句通过 obj.__dict__显示实例的输出时,我可以看到 var_1 被赋值为 1,var_1 被赋值为 2,而 var_3 被赋值为 3。

现在,假设我想在最初构建实例时更改此实例的 var_1 和 var_2 属性值,同时 var_3 属性保持原样。

要做到这一点很简单。 我定义了一个 __call__魔术方法,该方法允许重新定义 var_1 和 var_2 的属性。 可以隐式调用魔术方法,这意味着我只需调用 obj(200, 300),然后 __call__ 将被调用。当然,也可以显式调用 call 方法,例如 obj.__call__(200, 300)。但是第一种方法似乎更直观。最后,为了演示,我打印了实例的 ID 以明确表明我们已经操纵了同一对象。

1583478760472512.png

可以通过两种方式定义 call 方法。参数可以直接传递到调用方法中,或者,可以使用 *vars 参数,该参数捕获所有传递的参数并将它们存储在元组中,该元组可以如上所示进行解压缩。

10.png

该示例的源代码可以在下面找到。

11.png

总结 

 魔术方法可以使我们能够访问核心语法功能,从而丰富了我们的类设计。在第一个示例中,我们两全其美。我们可以从内置列表类继承,并修改该类中的特定方法以自定义行为。getitem,setitem 和 delitem 均已修改,但是通过继承,我们仍然能够使用列表的内置 init 和 repr() 方法。

我们可以非常轻松地将对象的使用传达给其他开发人员。 在提供的示例中,我们需要告诉开发人员的其他事情是,我们的类的行为就像一个列表,只是略有不同,在这里我们放弃了零索引的概念。无需学习新的方法名称或新的接口。

此外,还演示了调用魔术方法。 调用实例是更改对象的状态的一种直观而优雅的方式。

THE END

免责声明:本文来自互联网新闻客户端自媒体,不代表本网的观点和立场。

合作及投稿邮箱:E-mail:editor@tusaishared.com

上一篇:解构 BERT:从 1 亿个参数中提炼出 6 个模式

下一篇:为什么不应该在内部开发机器人流程自动化(RPA)项目

用户评价
全部评价

热门资源

  • Python 爬虫(二)...

    所谓爬虫就是模拟客户端发送网络请求,获取网络响...

  • TensorFlow从1到2...

    原文第四篇中,我们介绍了官方的入门案例MNIST,功...

  • TensorFlow从1到2...

    “回归”这个词,既是Regression算法的名称,也代表...

  • 机器学习中的熵、...

    熵 (entropy) 这一词最初来源于热力学。1948年,克...

  • TensorFlow2.0(10...

    前面的博客中我们说过,在加载数据和预处理数据时...