自定义类排序:没有抛出错误,Python 测试是为了什么? [英] Custom class ordering: no error thrown, what is Python testing for?

查看:70
本文介绍了自定义类排序:没有抛出错误,Python 测试是为了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

没有指定对象的相等比较属性,Python在使用><时仍然在做一些事情.如果您不指定 __gt____lt__,Python 实际上比较这些对象的依据是什么?我希望这里会出现不受支持的操作数错误,因为您在尝试将两个对象添加在一起而不定义 __add__ 时会遇到这种错误.

<代码>在 [1]: class MyObject(object):...:     经过...:在 [2]: class YourObject(object):...:     经过...:在 [3] 中:我 = MyObject()在 [4] 中:你 = YourObject()[5]中:我>你出[5]:假在[6]中:你>我输出[6]:真

解决方案

对对象强加任意顺序.排序仅定义为在程序执行中稳定.

这意味着在比较任意对象时,由 Python 实现来定义排序.如果类型相同,CPython 使用内存地址(来自 C来源):

if (v->ob_type == w->ob_type) {/* 比较这些指针时,必须将它们强制转换为* 整数类型(即 Py_uintptr_t,我们对 C9X 的拼写* uintptr_t).ANSI 指定指针比较其他* than == 和 != 到非相关结构是未定义的.*/Py_uintptr_t vv = (Py_uintptr_t)v;Py_uintptr_t ww = (Py_uintptr_t)w;返回 (vv  ww) ?1:0;}

相同的值是id()函数的基础,也表示在自定义类的默认repr()字符串中,所以它可能appear 类的 repr() 决定了排序.这只是内存地址.

对于不同类型的对象,使用类型name代替(类似数字的类型排序在其他类型之前),如果类型不同但它们的名称相同,代码回退到类型的内存地址(而不是类型相同时实例的内存地址).

这种隐式排序被认为是语言中的错误,并且已经在 Python 3 中修复:

<块引用>

排序比较运算符(<<=>=>)当操作数没有有意义的自然顺序时,引发 TypeError 异常.

这适用于未实现必要的排序挂钩:

<预><代码>>>>类 Foo(): 通过...>>>Foo() <富()回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中类型错误:无法排序的类型:Foo() <富()

Without specifying the equality comparison properties of objects, Python is still doing something when using > and <. What is Python actually comparing these objects by if you don't specify __gt__ or __lt__? I would expect an unsupported operand error here, as you get when trying to add two objects together without defing __add__.


In [1]: class MyObject(object):
   ...:     pass
   ...: 
In [2]: class YourObject(object):
   ...:     pass
   ...: 
In [3]: me = MyObject()
In [4]: you = YourObject()
In [5]: me > you
Out[5]: False
In [6]: you > me
Out[6]: True

解决方案

An arbitrary order is imposed for objects. The ordering is only defined to be stable within a program execution.

This means it's up to the Python implementation to define an ordering when comparing arbitrary objects. CPython uses the memory address if the types are the same (from the C source):

if (v->ob_type == w->ob_type) {
    /* When comparing these pointers, they must be cast to
     * integer types (i.e. Py_uintptr_t, our spelling of C9X's
     * uintptr_t).  ANSI specifies that pointer compares other
     * than == and != to non-related structures are undefined.
     */
    Py_uintptr_t vv = (Py_uintptr_t)v;
    Py_uintptr_t ww = (Py_uintptr_t)w;
    return (vv < ww) ? -1 : (vv > ww) ? 1 : 0;
}

The same value is the basis for the id() function, and is also represented in the default repr() string for custom classes, so it may appear that the repr() of classes determine ordering. It's only the memory address that does.

For objects that are not the same type, the type name is used instead (with number-like types sorting before others), and if the types differ but their names are the same, the code falls back to the memory address of the type (as opposed to the memory address of the instance when the types are the same).

This implicit ordering has been considered an error in the language, and has been remedied in Python 3:

The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering.

This applies to custom classes that do not implement the necessary ordering hooks:

>>> class Foo(): pass
... 
>>> Foo() < Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: Foo() < Foo()

这篇关于自定义类排序:没有抛出错误,Python 测试是为了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆