我正在写一个封装任何任意对象(包括简单类型)的类。 我希望" is"关键字对封装的值进行操作,例如以下行为:
Wrapper(True) is True -> True
Wrapper(False) is True -> False
Wrapper(None) is None -> True
Wrapper(1) is 1 -> True
我可以重写任何对象方法以获得此行为吗?
不能重载is,and和or。
Python文档中的任何地方都有吗?无法找到任何可以验证这一点的东西。
唯一的参考是它们在langref的3.4中不存在。 docs.python.org/reference/datamodel.html#special-method-names
这个答案很老了。最新的Python版本仍然适用吗?
@Fran:是的。关于这些运算符的行为没有改变。
我想我知道为什么is无法覆盖。字典查找和集合查找使用is进行快速相等性检查,因为__eq__是可覆盖的,并且可能确实很慢。如果is行为是可替代的,则将无法保证快速的字典查找,这将不利于python的性能。
python3在这里:and和or似乎可以被重载,并带有__and__,__rand__,__or__,__ror__。在控制台中键入dir(int)以说服自己。编辑:我不好,他们重载了&和|,而不是and和or
通常,如果要测试值的相等性(如果x为1,或者为True,或者为None),则无论如何都要使用==运算符。如果要使用is运算符,通常是在测试是否有其他内容在引用其他内容,例如list1 is list2。
如果要为==定义特殊行为,则可以在类定义中定义__eq__。
x is 1是危险的,但是x is None完全可以。 True,False和None保证是单例,并且我认为C-5中也静态分配了-5到257之间的整数,但是您可以创建与is相同的整数之一。
is本身不能重载,但是您可能对其他适用于您的用例的"反射"魔术方法感兴趣(因为您正在查看此线程):
__instancecheck__(self, instance)
Checks if an instance is an instance of the class you defined (e.g. isinstance(instance, class).
__subclasscheck__(self, subclass)
Checks if a class subclasses the class you defined (e.g. issubclass(subclass, class)).
No. is, and, and or cannot be overloaded.
确实。我相信关键字是保留的,不能重载或更改。
看到:
http://docs.python.org/2/reference/lexical_analysis.html#keywords
"以下标识符用作保留字或语言的关键字,不能用作普通标识符。"
清单是:
['和','as','assert','break','class','continue','def','del','elif','else','except','exec','最终","用于","从","全局","如果","导入","在","是"," lambda","非","或","通过","打印" ,"提高","返回","尝试","同时","有","收益"]
可以通过命令查看此列表
keyword.kwlist
(不要忘了先导入关键字)
也:
keyword.iskeyword('is')
返回真
更新:
我的回答很差,我应该感到很难过。
我自己搞砸了。我不知道为什么我没有注意到...
第二次尝试:
以下文档提供了有关类的可自定义行为的完整列表。这包括重写和重载运算符的所有方法。不包括"是"。
http://docs.python.org/2/reference/datamodel.html#special-method-names
尽我所能。
但是del可以重载,例如,您可以重载del x[i]或del x.attr。问题在于是否可以更改语义,而不是语法。
in可以直接重载。在上下文管理器中,as可以部分重载。 import和for可以间接过载。