【问题标题】:python: class override "is" behaviorpython:类覆盖“是”行为
【发布时间】:2011-04-28 22:32:07
【问题描述】:

我正在编写一个封装任意对象的类,包括简单类型。我想让“is”关键字对封装的值进行操作,比如这个行为:

Wrapper(True) is True -> True
Wrapper(False) is True -> False
Wrapper(None) is None -> True
Wrapper(1) is 1 -> True

有没有我可以重写的对象方法来获得这种行为?

【问题讨论】:

    标签: python


    【解决方案1】:

    没有。 isandor 不能重载。

    【讨论】:

    • 这在 Python 文档中的任何地方吗?找不到任何可以验证这一点的东西。
    • 唯一的参考是它们在 langref 的§3.4 中的缺席。 docs.python.org/reference/datamodel.html#special-method-names
    • 这个答案已经很老了。对于最新的 Python 版本,这仍然适用吗?
    • @Fran:是的。这些运算符的行为没有改变。
    • 我想我知道为什么is 不能被覆盖。字典查找和集合查找使用is 进行快速相等检查,因为__eq__ 是可覆盖的并且可能非常慢。如果is 行为是可覆盖的,则无法保证快速的字典查找,这将不利于 python 的性能。
    【解决方案2】:

    通常,如果您想根据值来测试相等性(如果 x 为 1、True 或 None),无论如何您都应该使用 == 运算符。如果你想使用is 操作符,你通常会测试某个东西是否引用了其他东西,比如list1 is list2

    如果要为== 定义特殊行为,可以在类定义中定义__eq__

    【讨论】:

    • x is 1 很危险,但x is None 完全没问题。 TrueFalseNoneguaranteed to be singletons,我 认为 整数 -5 到 257 也在 CPython 中静态分配,但您可能能够创建这些整数之一这不是is 相同。
    【解决方案3】:

    is 本身不能重载,但您可能对其他可能适合您的用例的"Reflection" magic methods 感兴趣(因为您正在查看此线程):

    __instancecheck__(self, instance) 检查实例是否是您定义的类的实例(例如isinstance(instance, class)

    __subclasscheck__(self, subclass) 检查一个类是否是您定义的类的子类(例如issubclass(subclass, class))。

    【讨论】:

      【解决方案4】:

      没有。 isandor 不能重载。

      确实如此。我认为关键字是保留的,不能重载或更改。

      见: http://docs.python.org/2/reference/lexical_analysis.html#keywords

      "以下标识符作为保留字,或者语言的关键字,不能作为普通标识符使用。"

      名单如下: ['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', ' finally'、'for'、'from'、'global'、'if'、'import'、'in'、'is'、'lambda'、'not'、'or'、'pass'、'print' , 'raise', 'return', 'try', 'while', 'with', 'yield']

      这个列表可以通过命令查看

      keyword.kwlist

      (别忘了先导入关键字)

      还有:

      keyword.iskeyword('is')

      返回真


      更新:

      我的回答很糟糕,我应该感到难过。

      我自己搞砸了 del 。我不知道为什么我没有注意到...

      第二次尝试:

      以下文档提供了类上可自定义行为的完整列表。这包括用于覆盖和重载运算符的所有方法。不包括“是”。

      http://docs.python.org/2/reference/datamodel.html#special-method-names

      尽我所能。

      【讨论】:

      • 但是del可以重载,例如,你可以重载del x[i]del x.attr。问题在于语义是否可以改变,而不是语法。
      • in 可以直接重载。 as 可以在上下文管理器中部分重载。 importfor 可以间接重载。
      猜你喜欢
      • 1970-01-01
      • 2020-06-16
      • 1970-01-01
      • 2016-05-27
      • 2017-05-11
      • 2020-07-02
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      相关资源
      最近更新 更多