GVKun编程网logo

为什么/何时在Python中`x == y`调用`y .__ eq __(x)`?(python max=x>y?x:y为什么非法)

22

对于为什么/何时在Python中`x==y`调用`y.__eq__感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解x`?,并且为您提供关于arr.__len__()是在Python中获取数组

对于为什么/何时在Python中`x == y`调用`y .__ eq __感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解x`?,并且为您提供关于arr .__ len __()是在Python中获取数组长度的首选方法吗?、module .__ init __()在Python中最多接受2个参数错误、Python-为什么总是在__new __()之后调用__init __()?、python中if __name__ == ''__main__''是什么?的宝贵知识。

本文目录一览:

为什么/何时在Python中`x == y`调用`y .__ eq __(x)`?(python max=x>y?x:y为什么非法)

为什么/何时在Python中`x == y`调用`y .__ eq __(x)`?(python max=x>y?x:y为什么非法)

Python文档明确指出了x==y调用x.__eq__(y)。但是似乎在许多情况下,情况恰恰相反。它何时何地发生的原因在哪里记录,如何确定我的对象__cmp____eq__方法将被调用。

编辑:只是为了澄清,我知道__eq__在优选中调用__cmp__,但是我不清楚为什么y.__eq__(x)优先于调用x.__eq__(y),而后者是文档状态将发生的原因。

>>> class TestCmp(object):...     def __cmp__(self, other):...         print "__cmp__ got called"...         return 0... >>> class TestEq(object):...     def __eq__(self, other):...         print "__eq__ got called"...         return True... >>> tc = TestCmp()>>> te = TestEq()>>> >>> 1 == tc__cmp__ got calledTrue>>> tc == 1__cmp__ got calledTrue>>> >>> 1 == te__eq__ got calledTrue>>> te == 1__eq__ got calledTrue>>> >>> class TestStrCmp(str):...     def __new__(cls, value):...         return str.__new__(cls, value)...     ...     def __cmp__(self, other):...         print "__cmp__ got called"...         return 0... >>> class TestStrEq(str):...     def __new__(cls, value):...         return str.__new__(cls, value)...     ...     def __eq__(self, other):...         print "__eq__ got called"...         return True... >>> tsc = TestStrCmp("a")>>> tse = TestStrEq("a")>>> >>> "b" == tscFalse>>> tsc == "b"False>>> >>> "b" == tse__eq__ got calledTrue>>> tse == "b"__eq__ got calledTrue

编辑:从马克·迪金森的答案和评论中,它看起来像是:

  1. 丰富的比较替代 __cmp__
  2. __eq__是它自己的__rop__,以它的__op__(以及类似的__lt____ge__等等)
  3. 如果左对象是内置类或新样式类,而右对象是其子类,则__rop__在左对象之前尝试右对象__op__

这解释了TestStrCmp示例中的行为。
TestStrCmp是的子类,str但没有实现自己的子类,__eq__因此两种情况下__eq__ofstr优先(例如,由于规则1而tsc== "b"调用)。b.__eq__(tsc)``__rop__

TestStrEq示例中,tse.__eq__在两种情况下都被调用,因为它TestStrEq是的子类,str因此优先调用它。

TestEq示例中,两次TestEq实现(__eq__int不是__eq__两次)都被调用(规则1)。

但我仍然不了解的第一个示例TestCmptc不是intAFAICT的子类,因此1.__cmp__(tc)应该调用AFAICT ,但不是。

答案1

小编典典

您缺少通常行为的关键例外:当右侧操作数是左侧操作数类的子类的实例时,将首先调用右侧操作数的特殊方法。

请参阅以下文档:

http://docs.python.org/reference/datamodel.html#coercion-
rules

特别是以下两段:

对于xy,首先 x.__op__(y)尝试。如果未实现或返回
NotImplemented,请y.__rop__(x)尝试。如果这也没有实现或返回NotImplemented,则引发TypeError异常。但是请参见以下异常:

上一项的例外:如果左操作数是内置类型或新样式类的实例,而右操作数是该类型或类的适当子类的实例,并且覆盖基数的
__rop__()方法,则右操作的__rop__()方法是左操作的尝试过__op__() 的方法。

arr .__ len __()是在Python中获取数组长度的首选方法吗?

arr .__ len __()是在Python中获取数组长度的首选方法吗?

在Python中,以下是获取元素数量的唯一方法吗?

arr.__len__()

如果是这样,为什么会有奇怪的语法?

module .__ init __()在Python中最多接受2个参数错误

module .__ init __()在Python中最多接受2个参数错误

我有3个文件,factory_imagenet.py,imdb.py和imagenet.py

factory_imagenet.py具有:

import datasets.imagenet

它也有一个函数调用

datasets.imagenet.imagenet(split,devkit_path))
...

imdb.py具有:

class imdb(object):
def __init__(self,name):
    self._name = name
    ...

imagenet.py具有:

import datasets
import datasets.imagenet
import datasets.imdb

它也有

class imagenet(datasets.imdb):
    def __init__(self,image_set,devkit_path=None):
        datasets.imdb.__init__(self,image_set)

所有这三个文件都在数据集文件夹中。

当我运行与这些文件交互的另一个脚本时,出现此错误:

Traceback (most recent call last):
  File "./tools/train_faster_rcnn_alt_opt.py",line 19,in <module>
    from datasets.factory_imagenet import get_imdb
  File "/mnt/data2/abhishek/py-faster-rcnn/tools/../lib/datasets/factory_imagenet.py",line 12,in <module>
    import datasets.imagenet
  File "/mnt/data2/abhishek/py-faster-rcnn/tools/../lib/datasets/imagenet.py",line 21,in <module>
    class imagenet(datasets.imdb):
TypeError: Error when calling the metaclass bases
module.__init__() takes at most 2 arguments (3 given)

这是什么问题,如何解决此类继承问题的直观解释是什么?

Python-为什么总是在__new __()之后调用__init __()?

Python-为什么总是在__new __()之后调用__init __()?

如何解决Python-为什么总是在__new __()之后调用__init __()??

使用__new__时,你需要控制一个新实例的创建。

使用 __init__时,你需要一个新的实例的控件初始化。

__new__是实例创建的第一步。首先调用它,它负责返回类的新实例。

相反, __init__不返回任何东西。创建实例后,它仅负责初始化实例。

通常,除非你要__new继承不可变类型(如str,int,unicode或tuple),否则无需覆盖__`。

从2008年4月发布:何时使用__new__vs __init__?在mail.python.org上。

你应该考虑到你通常想通过工厂来完成的工作,这是最好的方法。使用__new__不是一个好的清洁解决方案,因此请考虑使用工厂。在这里,你有一个很好的工厂示例。

解决方法

我只是想简化我的一个类,并以与flyweight设计模式相同的样式介绍了一些功能。

但是,对于为什么__init__总是被称为after ,我有点困惑__new__。我没想到这一点。谁能告诉我为什么会这样,否则我如何实现此功能?(除了将实现放到__new__hacky中之外)。

这是一个例子:

class A(object):
    _dict = dict()

    def __new__(cls):
        if ''key'' in A._dict:
            print "EXISTS"
            return A._dict[''key'']
        else:
            print "NEW"
            return super(A,cls).__new__(cls)

    def __init__(self):
        print "INIT"
        A._dict[''key''] = self
        print ""

a1 = A()
a2 = A()
a3 = A()

输出:

NEW
INIT

EXISTS
INIT

EXISTS
INIT

为什么?

python中if __name__ == ''__main__''是什么?

python中if __name__ == ''__main__''是什么?

__name____main__认识

**作用:**一般用于测试程序的功能,if __name__ == ''__main__'':下面的代码会被执行,但当前.py文件被当做模块导入的时候,main下面的代码就不会被执行,防止测试代码被执行。

语法:

if __name__ == ''__main__'':
            要执行的测试模块
 

if __name__ == "__main__":可以看成是python程序的入口,就像java中的main()方法,但不完全正确。

.py文件中,除了def后面定义函数外的代码都会被认为是“main”方法中的内容,从而从上而下执行。

如果只是写一个print(''hello world''),那这一句话就是一个程序,因此不需要所谓的"main"方法入口,直接运行测试就可以。

但如果是测试函数功能,我们就需要在.py文件中写上if__name__=="__main__",再调用函数,当然,如果你不写的话,也没关系,也可以直接将函数加括号进行调用。

我们写的目的就是防止后面会把当前.py文件当做模块导入其他.py文件中,从而误触发测试代码。

__name__的变化

1、__name__其实就是一个内置属性,在自己的py文件中被执行,__name__属性的值就是__main__

示例代码:

# test.py
print("first")
 
 
def say_hello():
    print(__name__)
 
 
if __name__ == ''__main__'':
    print(__name__)
    say_hello()

运行结果:

first
__main__
__main__

2、将test.py文件导入其他文件中,__name__就会变为当前模块的名字,例如:__test__

实例代码:

# work.py
 
import test  # 导入test
 
 
if __name__ == ''__main__'':
    test.say_hello()
    print(__name__)

执行结果:

first
test
__main__

**总结:**python不像JAVA中一样拥有main()方法的特点。所谓的入口其实也就是一个if条件语句,判断成功就执行下面if中的代码。JAVA等其他语言中会有特定的内置函数去识别main()方法入口,在main()方法中从上而下执行。

原文出处:https://www.cnblogs.com/cnhyk/p/12410958.html

今天关于为什么/何时在Python中`x == y`调用`y .__ eq __x`?的分享就到这里,希望大家有所收获,若想了解更多关于arr .__ len __()是在Python中获取数组长度的首选方法吗?、module .__ init __()在Python中最多接受2个参数错误、Python-为什么总是在__new __()之后调用__init __()?、python中if __name__ == ''__main__''是什么?等相关知识,可以在本站进行查询。

本文标签: