当前位置: 首页 > 知识库问答 >
问题:

分配和定义Python魔术方法

欧阳正德
2023-03-14

考虑以下令人厌恶的类别:

class MapInt:
    __call__ = int

    def __sub__(self, other):
        return map(self, other)

    __add__ = map

然后,可以通过MapInt() - lst调用map(int,lst),即

assert list(MapInt() - ['1','2','3'])) == [1,2,3]    # passes

但是,添加并不那么合作:

assert list(MapInt() + ['1','2','3'])) == [1,2,3]    # TypeError: map() must have at least two arguments.

这种陌生感可以通过直接调用魔法方法来解决:

assert list(MapInt.__add__(MapInt(), ['1','2','3']))   == [1,2,3]    # passes
assert list(MapInt().__add__(MapInt(), ['1','2','3'])) == [1,2,3]    # passes

所以我的问题是,是什么给了我们?直接分配<code>__add_

共有2个答案

萧波峻
2023-03-14

它与“分配”和/或“定义”之间的区别无关。您甚至可以在创建类之后动态添加函数。它们都是一样的。

这是描述符的行为。

class Function:
    ...

    def __get__(self, obj, objtype=None):
        "Simulate func_descr_get() in Objects/funcobject.c"
        if obj is None:
            return self
        return MethodType(self, obj)

您的__sub__是一个描述符。如果从实例调用它,它将为您提供一个 MethodType 对象,其第一个参数填充了对实例的引用,这就是第一个 assert 语句工作的原因。

实际上,所有用户定义的函数都是描述符,但是内置的可调用(函数/类)(如map)或其他可调用对象(如类)不是这样,除了它们的第一个参数将被填充一些东西。

单于经纬
2023-03-14

这在Python数据模型中有所阐述:

注意,从函数对象到实例方法对象的转换发生在每次从实例[...]还要注意,这种转换只发生在用户定义的函数中;其他可调用对象(以及所有不可调用对象)无需转换即可被检索。

因为< code>map是一个内置函数,而不是用户定义的函数,所以没有到实例方法的转换,所以没有添加< code>self参数。

 类似资料:
  • Python 中有很多 __ 开始和结尾的特殊方法,它们多是所有类型都拥有的,通过实现这些 特殊方法可以实现很多有意思的功能,比如最常使用的 __str__、__repr__ 和 __unicode__ 这三个就可以用于输出对象的字符串结果。 GitHub 上有篇翻译不错: 翻译 原文 魔术方法与语法糖 Lisp 的语法极其简单,主要语法“S 表达式”非常接近于数学中的波兰表达式,写法如下: (+

  • 问题内容: 除非我完全误解,否则and 方法应该允许→ 和的重载。 例如,以下语句应调用该方法: 并且以下应使用该方法: 这在我的代码中不起作用,并且可以通过以下简单示例重现: 这只会导致: 在那儿放一些电话表明它根本没打。 现在,我只是说了一下要解决的问题,并在目前需要的地方手动使用它,但这不是很动态,并且需要知道“重载”代码实际上没有被调用,除非专门调用。我想知道这是否不是应该以我所理解的方式

  • 问题内容: 我最近一直在使用Python,而我发现有点奇怪的是,广泛使用了“魔术方法”,例如,使其长度可用,一个对象实现一个方法,然后在你写。 我只是想知道为什么对象不能简单地定义一个方法并直接将其作为对象的成员来调用,例如?我敢肯定,Python这么做的确有充分的理由,但是作为一个新手,我还没有弄清楚它们到底是什么。 问题答案: AFAIK在这方面很特殊,并且具有历史渊源。 这是FAQ中的报价:

  • 本文向大家介绍php 魔术方法详解,包括了php 魔术方法详解的使用技巧和注意事项,需要的朋友参考一下 从PHP 5以后的版本,PHP中的类就可以使用魔术方法了。其规定以两个下划线(__)开头的方法都保留为魔术方法,所以建议大家函数名最好不用__开头,除非是为了重载已有的魔术方法。PHP 将所有以 _ _(两个下划线)开头的类方法保留为魔术方法。 __toString() 和__invoke()

  • 1.13.1 魔术方法: 在Python中的面向对象中有很多魔术方法如: __init__: 构造函数,在生成对象时调用 __del__: 析构函数,释放对象时使用 __str__: 使用print(对象)或者str(对象)的时候触发 __repr__: 在使用repr(对象)的时候触发 __setitem__ : 按照索引赋值:每当属性被赋值的时候都会调用该方法:self._

  • 本文向大家介绍Python类型转换的魔术方法详解,包括了Python类型转换的魔术方法详解的使用技巧和注意事项,需要的朋友参考一下 本文讨论python中将某个复杂对象转换为简单对象或数据类型的常用魔术放啊,这些在编程中是十分有用的。 1、__str__方法。 在讲解本方法前我们先打开一个jupyter notebook,随意创建一个类如下,使用str()方法输出该类的实例看看返回了什么: Out