gpt4 book ai didi

Python type() or __class__, == or is

转载 作者:IT老高 更新时间:2023-10-28 20:36:48 26 4
gpt4 key购买 nike

我想测试一个对象是否是一个类的实例,并且只有这个类(没有子类)。我可以这样做:

obj.__class__ == Foo
obj.__class__ is Foo
type(obj) == Foo
type(obj) is Foo

有理由选择一个而不是另一个吗? (性能差异、陷阱等)

换句话说:a) 使用 __class__type(x) 之间有什么实际区别吗? b) 使用 is 比较类对象总是安全的吗?


更新:感谢大家的反馈。我仍然对类对象是否是单例感到困惑,我的常识说它们是,但是很难得到确认(尝试谷歌搜索“python”,“class”和“unique”或“singleton”) .

我还想澄清一下,对于我的特殊需求,“更便宜”的解决方案是最好的,因为我正在尝试优化几个专业类(class)中的大部分(几乎达到目的明智的做法是放弃 Python 并在 C 中开发该特定模块)。但问题背后的原因是为了更好地理解语言,因为它的一些功能有点太模糊了,我无法轻易找到这些信息。这就是为什么我让讨论扩展一点而不是满足于 __class__ is,所以我可以听到更有经验的人的意见。到目前为止,它非常富有成效!

我运行了一个小测试来对 4 个备选方案的性能进行基准测试。探查器结果是:

               Python  PyPy (4x)
type() is 2.138 2.594
__class__ is 2.185 2.437
type() == 2.213 2.625
__class__ == 2.271 2.453

不出所料,在所有情况下,is 的表现都优于 ==type() 在 Python 中表现更好(快 2%),__class__ 在 PyPy 中表现更好(快 6%)。有趣的是,__class__ == 在 PyPy 中的表现优于 type() is


更新 2: 很多人似乎不明白我所说的“类是单例”是什么意思,所以我将举例说明:

>>> class Foo(object): pass
...
>>> X = Foo
>>> class Foo(object): pass
...
>>> X == Foo
False
>>> isinstance(X(), Foo)
False
>>> isinstance(Foo(), X)
False

>>> x = type('Foo', (object,), dict())
>>> y = type('Foo', (object,), dict())
>>> x == y
False
>>> isinstance(x(), y)
False

>>> y = copy.copy(x)
>>> x == y
True
>>> x is y
True
>>> isinstance(x(), y)
True
>>> y = copy.deepcopy(x)
>>> x == y
True
>>> x is y
True
>>> isinstance(x(), y)
True

如果有N个type类型的对象并不重要,给定一个对象,只有一个是它的类,因此在这种情况下进行比较以供引用是安全的。而且由于引用比较总是比值(value)比较便宜,我想知道我上面的断言是否成立。我得出的结论是确实如此,除非有人提出相反的证据。

最佳答案

对于老式类,有区别:

>>> class X: pass
...
>>> type(X)
<type 'classobj'>
>>> X.__class__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: class X has no attribute '__class__'
>>> x = X()
>>> x.__class__
<class __main__.X at 0x171b5d50>
>>> type(x)
<type 'instance'>

新型类的重点是统一类和类型。从技术上讲,__class__ 是唯一适用于新式和旧式类实例的解决方案,但它也会对旧式类对象本身抛出异常。您可以在任何对象上调用 type(),但并非每个对象都有 __class__。此外,你可以用 __class__ 用一种你不能用 type() 捣乱的方式来捣乱。

>>> class Z(object):
... def __getattribute__(self, name):
... return "ham"
...
>>> z = Z()
>>> z.__class__
'ham'
>>> type(z)
<class '__main__.Z'>

就我个人而言,我通常有一个只包含新样式类的环境,并且就样式而言,我更喜欢使用 type(),因为我通常更喜欢存在内置函数而不是使用魔法属性。例如,我也更喜欢 bool(x) 而不是 x.__nonzero__()

关于Python type() or __class__, == or is,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9610993/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com