Python中的旧样式类和新样式类有什么区别?什么时候我应该用一种或另一种?
当前回答
New-style类继承自object,并且在Python 2.2以后必须这样编写(即类Classname(object):而不是类Classname:)。核心变化是统一类型和类,这样做的好处是允许从内置类型继承。
更多细节请阅读描述介绍。
其他回答
新旧样式类之间的重要行为变化
超级补充道 MRO变更(解释如下) 描述符添加 除非派生自Exception,否则不能引发new样式类对象(如下例) __slots__补充道
MRO(方法解决顺序)更改
它在其他回答中提到过,但这里有一个经典MRO和C3 MRO之间区别的具体例子(用于新风格的职业)。
问题是在多重继承中搜索属性(包括方法和成员变量)的顺序。
经典类从左到右进行深度优先搜索。停在第一根火柴上。它们没有__mro__属性。
class C: i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass
assert C12().i == 0
assert C21().i == 2
try:
C12.__mro__
except AttributeError:
pass
else:
assert False
新型课程MRO在一个英语句子中合成起来更加复杂。这里有详细的解释。它的一个属性是只搜索一次基类的所有派生类。它们有__mro__属性,显示搜索顺序。
class C(object): i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass
assert C12().i == 2
assert C21().i == 2
assert C12.__mro__ == (C12, C1, C2, C, object)
assert C21.__mro__ == (C21, C2, C1, C, object)
除非派生自Exception,否则不能引发新的样式类对象
在Python 2.5左右,可以引发许多类,在Python 2.6左右,这被删除了。Python 2.7.3:
# OK, old:
class Old: pass
try:
raise Old()
except Old:
pass
else:
assert False
# TypeError, new not derived from `Exception`.
class New(object): pass
try:
raise New()
except TypeError:
pass
else:
assert False
# OK, derived from `Exception`.
class New(Exception): pass
try:
raise New()
except New:
pass
else:
assert False
# `'str'` is a new style object, so you can't raise it:
try:
raise 'str'
except TypeError:
pass
else:
assert False
对于属性查找,旧样式的类仍然稍微快一些。这通常并不重要,但在性能敏感的Python 2中可能很有用。x代码:
In [3]: class A: ...: def __init__(self): ...: self.a = 'hi there' ...: In [4]: class B(object): ...: def __init__(self): ...: self.a = 'hi there' ...: In [6]: aobj = A() In [7]: bobj = B() In [8]: %timeit aobj.a 10000000 loops, best of 3: 78.7 ns per loop In [10]: %timeit bobj.a 10000000 loops, best of 3: 86.9 ns per loop
Guido写了关于新型类的内幕,这是一篇关于Python中的新型和老式类的很棒的文章。
Python 3只有new-style类。即使你写了一个“老式类”,它也是隐式地从object派生的。
新型类具有一些老式类所缺乏的高级特性,如super,新的C3 mro,一些神奇的方法等。
Declaration-wise:
New-style类继承自object或另一个New-style类。
class NewStyleClass(object):
pass
class AnotherNewStyleClass(NewStyleClass):
pass
老式的类没有。
class OldStyleClass():
pass
注意事项:
Python 3不支持旧样式的类,所以上面提到的任何一种形式都会产生新样式的类。
New-style类继承自object,并且在Python 2.2以后必须这样编写(即类Classname(object):而不是类Classname:)。核心变化是统一类型和类,这样做的好处是允许从内置类型继承。
更多细节请阅读描述介绍。
推荐文章
- 如何使x轴和y轴的刻度相等呢?
- Numpy在这里函数多个条件
- 在Python中,使用argparse只允许正整数
- 如何排序mongodb与pymongo
- 不可变与可变类型
- 列表是线程安全的吗?
- 字符串不能识别为有效的日期时间“格式dd/MM/yyyy”
- 操作系统。makdirs在我的路径上不理解“~”
- 如何在Django模板中获得我的网站的域名?
- 在django Forms中定义css类
- 如何在Python中scp ?
- Numpy Max vs amax vs maximum
- 我应该在.gitignore文件中添加Django迁移文件吗?
- 每n行有熊猫
- 实例属性attribute_name定义在__init__之外