Python中如何实现“关键字”?
-
24-10-2019 - |
题
... 这 is
可以用于字符串平等的关键字。
>>> s = 'str'
>>> s is 'str'
True
>>> s is 'st'
False
我尝试了两者 __is__()
和 __eq__()
但是他们没有工作。
>>> class MyString:
... def __init__(self):
... self.s = 'string'
... def __is__(self, s):
... return self.s == s
...
>>>
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work
False
>>>
>>> class MyString:
... def __init__(self):
... self.s = 'string'
... def __eq__(self, s):
... return self.s == s
...
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work, but again failed
False
>>>
解决方案
测试字符串 is
仅在弦乐实习时起作用。除非您真的知道自己在做什么并明确地做什么 实习 你应该的琴弦 绝不 利用 is
在弦上。
is
测试 身份, , 不是 平等. 。这意味着Python只是比较对象所在的内存地址。 is
基本上回答了“我有两个名称的同一对象的名字吗?” - 超负荷是没有意义的。
例如, ("a" * 100) is ("a" * 100)
是 错误的. 。通常,python将每个字符串写入不同的内存位置,大部分用于字符串文字。
其他提示
这 is
操作员等同于比较 id(x)
值。 id
目前已实施将指针作为比较。所以你不能超载 is
本身,afaik你不能超负荷 id
任何一个。
所以,你不能。在Python中很不寻常,但这是。
Python is
关键字测试对象身份。您不应使用它来测试字符串平等。它似乎经常起作用,因为Python的实现,例如许多非常高级的语言的实现,都可以执行字符串的“实习”。也就是说,字符串文字和值在内部保存在哈希列表中,而与同一对象相同的引用。 (这是可能的,因为Python弦是不变的)。
但是,与任何实施细节一样,您不应依靠这一点。如果要测试平等,请使用==操作员。如果您真的想测试对象身份,请使用 is
---我很难想到您应该关心字符串对象身份的情况。不幸的是,由于上述的实习,您无法指望两个字符串某种程度上“故意”相同的对象引用。
这 is
关键字比较对象(或者,更确切地说,是否将两个引用与同一对象进行比较)。
我认为这就是为什么没有提供您自己的实施的机制。
有时碰巧在字符串上起作用,因为Python“巧妙地存储字符串”,因此当您创建两个相同的字符串时,它们会存储在一个对象中。
>>> a = "string"
>>> b = "string"
>>> a is b
True
>>> c = "str"+"ing"
>>> a is c
True
您可以希望在一个简单的“复制”示例中查看参考与数据比较:
>>> a = {"a":1}
>>> b = a
>>> c = a.copy()
>>> a is b
True
>>> a is c
False
如果您不害怕弄乱字节码,则可以拦截和补丁 COMPARE_OP
和 8 ("is")
在比较对象上调用钩子函数的论点。看着 dis
启动的模块文档。
而且不要忘记拦截 __builtin__.id()
如果有人会这样做 id(a) == id(b)
代替 a is b
.
当字符串以' - '开头时,无法将字符串变量与字符串值和两个字符串变量进行比较。我的Python版本是2.6.6
>>> s = '-hi'
>>> s is '-hi'
False
>>> s = '-hi'
>>> k = '-hi'
>>> s is k
False
>>> '-hi' is '-hi'
True
“ IS”比较对象身份,而==比较值。
例子:
a=[1,2]
b=[1,2]
#a==b returns True
#a is b returns False
p=q=[1,2]
#p==q returns True
#p is q returns True
你不能超载 is
操作员。您要超载的是 ==
操作员。这可以通过定义 __eq__
班上的方法。
您正在使用身份比较。 == 可能是您想要的。这个例外是您想检查一个项目是否是完全相同的对象,并且处于同一内存位置。在您的示例中,该项目不相同,因为一个类型(my_string)与另一个类型不同(my_string)。另外,没有someclass之类的东西。__is__
在Python(当然,除非您自己放在那里)。如果有,将对象与 是 简单地比较内存位置并不可靠。
当我第一次遇到 是 关键字,它也使我感到困惑。我会以为 是 和==没有什么不同。他们在许多对象上产生了解释器的相同输出。这种类型的假设实际上正是 是...是。这是python等效的“嘿,不要误解这两个物体。它们是不同的。措辞有很大不同,但一个点==另一个点。
对于一些有用的例子和一些文本,可以帮助有时令人困惑的差异访问 来自python.org的邮件主机的文档 由“ Danny Yoo”撰写
或者,如果那是离线的,请使用 未列出的糊剂 我用它的身体制成。
如果它们在大约20个左右的蓝色月亮(蓝色月亮是一个真实的事件)中,我都会引用代码示例
###
>>> my_name = "danny"
>>> your_name = "ian"
>>> my_name == your_name
0 #or False
###
###
>>> my_name[1:3] == your_name[1:3]
1 #or True
###
###
>>> my_name[1:3] is your_name[1:3]
0
###
断言错误很容易出现 是 关键字在比较对象时。例如,对象 一个 和 b 可能具有相同的价值并共享相同的内存地址。因此,做一个
>>> a == b
要评估
True
但是如果
>>> a is b
评估
False
您可能应该检查
>>> type(a)
和
>>> type(b)
这些可能是不同的,也是失败的原因。