gpt4 book ai didi

python - 为什么我们可以在Python中用字符串调用`__mod__`函数?

转载 作者:太空宇宙 更新时间:2023-11-04 10:14:06 25 4
gpt4 key购买 nike

我正在阅读python源代码:
https://hg.python.org/cpython/file/2.7/Lib/collections.py#l621

 def __repr__(self):

if not self:

return '%s()' % self.__class__.__name__

items = ', '.join(map('%r: %r'.__mod__, self.most_common()))

return '%s({%s})' % (self.__class__.__name__, items)


形成文件:

operator.mod(a, b)
operator.__mod__(a, b)¶
Return a % b.


我认为这是对的,

但是为什么 '%r: %r'.__mod__是正确的?

最佳答案

为什么字符串具有__mod__

__mod__在Python中实现%运算符的行为。对于字符串,%运算符为overloaded,可为我们提供字符串格式设置选项。如果a % ba mod b是数字,通常a会强制对b求值,对于字符串,我们可以更改%的行为,以便a % b实际上将b的元素插入到a如果a是字符串。

运算符重载在Python中的工作方式是每个中缀运算符-+-*/等(从Python 3.5开始,matrix multiplication operator @)-对应到被调用的类的基本定义中的特定方法。例如,对于+,它是__add__()。对于%,它是__mod__()。我们可以通过在类中简单地重新定义这些方法来重载这些方法。

如果我有类Foo,并且Foo实现了成员函数__add__(self, other),则可能使Foo() + bar的行为与+的常规定义大不相同。

换句话说,字符串格式化技术

'%s: %s' % (5,2)


在Python中实际调用

'%s: %s'.__mod__((5,2))


在幕后,其中为属于类 __mod__的对象定义了 string。在这种情况下,为字符串产生 __mod__()的方式只是 5: 2,而不是 '%s : %s' mod (5,2)的荒谬解释。



为什么在 __mod__中而不在 map中使用 __mod__()

map('%r: %r'.__mod__, self.most_common())的特定情况下,正在发生的事情是函数指针(需要一个更好的词-请注意,Python没有指针,但是暂时以这种方式思考也无妨) >应用于 __mod__中的每个元素,而不是函数 self.most_common()

这与 __mod__()一样。我们没有传递函数调用 map(int, "52"),而是以 int()的形式传递了对该函数的引用,并期望该函数由 int以及 map的第二个参数调用。即 map将在“ 52”的每个元素上调用。

正是由于这个原因,我们不能执行 int()。函数 map('%r: %r'.__mod__(), self.most_common())将在没有传入适当参数的情况下被调用并返回错误-我们想要的是对函数 '%r: %r'.__mod__()的引用,而不是我们可以随时随地引用和调用,这是通过调用 __mod__()完成的。



C ++类比

__mod____mod__的行为实际上与C ++中的函数指针的工作方式没有什么不同: __mod__()的函数指针仅由 foo()表示,即不带括号。类似的事情-但不完全相同-在这里发生。我在这里介绍它是因为它可以使区分更加清晰,因为从表面上看,指针看起来与正在发生的事情非常相似,而引入指针会导致一种相当熟悉的思维方式,足以满足此特定目的。

在C ++中,我们可以将函数指针传递给其他函数,并引入一种currying形式-例如,您可以通过另一个函数内部的常规 foo语法在元素上调用函数指针。在Python中,我们没有指针-我们有包装器对象,这些包装器对象可以引用底层的内存位置(但可以防止对其进行原始访问)。但是,出于我们的目的,最终效果是相同的。 @Bukuriu探索了注释中的差异。

基本上, foo()强制执行不带参数的评估。 __mod__()返回一个指向 __mod__的指针,然后该指针可以被另一个函数在适当的参数上调用。在内部,这就是 __mod__()的作用:获取一个函数指针(同样,这是一个类比),然后引用并在另一个元素上对其求值。

您可以自己看到:调用 map返回

<method-wrapper '__mod__' of str object at 0x7f92ed464690>


即包装对象,该包装对象引用了该函数的内存地址。同时,调用 '%s'.__mod__会返回错误:

TypeError: expected 1 arguments, got 0


因为多余的括号调用了 '%s'.__mod__()的求值,但发现没有参数。

关于python - 为什么我们可以在Python中用字符串调用`__mod__`函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36442389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com