【发布时间】:2012-03-25 13:01:12
【问题描述】:
我想测试一个对象是否是一个类的实例,并且只有这个类(没有子类)。我可以这样做:
obj.__class__ == Foo
obj.__class__ is Foo
type(obj) == Foo
type(obj) is Foo
有理由选择一个而不是另一个吗? (性能差异、陷阱等)
换句话说:a) 使用__class__ 和type(x) 之间有什么实际区别吗? b) 使用is比较类对象总是安全的吗?
更新:感谢大家的反馈。我仍然对类对象是否是单例感到困惑,我的常识说它们是,但是很难得到确认(尝试谷歌搜索“python”,“class”和“unique”或“singleton”) .
我还想澄清一下,对于我的特殊需求,“更便宜”的解决方案是最好的,因为我正在尝试优化少数专业课程中的大部分(几乎达到目的明智的做法是放弃 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 类型的对象并不重要,给定一个对象,只有一个是它的类,因此在这种情况下进行比较以供参考是安全的。而且由于参考比较总是比价值比较便宜,我想知道我上面的断言是否成立。我得出的结论是确实如此,除非有人提出相反的证据。
【问题讨论】:
-
如果你想知道哪个最适合你的使用,只需使用 timeit 模块进行测试即可。
-
@jsbueno 我不是这个意思。当然有很多实例,但只有一个是给定对象的“类”,对吧?换句话说,如果
x.__class__ == a和a == b然后a is b(当然是表现良好的__eq__),这就是我要确认/反驳的猜想。 -
标题是对我大脑语法单元的 DoS 攻击 :)
-
@mgibsonbr
if x.__class__ == a and a == b then a is b看这里-> Are classobjects singleton in python?