对象初始化期间缺少对 __init__
的调用¶
ID: py/missing-call-to-init
Kind: problem
Security severity:
Severity: error
Precision: high
Tags:
- reliability
- correctness
Query suites:
- python-security-and-quality.qls
与 Java 等静态类型语言不同,Python 允许在对象初始化期间调用方法时完全自由。但是,标准的面向对象原则适用于使用深度继承层次结构的 Python 类。因此,开发人员有责任确保在需要调用多个 __init__
方法时正确初始化对象。
如果在对象初始化期间未调用超类的 __init__
方法,则该对象很可能最终处于不正确状态。
在对象初始化期间,对超类的 __init__
方法的调用可能被省略
当子类调用错误类的
__init__
方法时。当省略对基类之一的
__init__
方法的调用时。当使用多重继承,一个类从多个基类继承,并且至少有一个基类在其自己的
__init__
方法中没有使用super()
时。
建议¶
要么小心地显式调用正确基类的 __init__
,要么在整个继承层次结构中使用 super()
。
或者将一个或多个类重构为使用组合而不是继承。
示例¶
在此示例中,使用了对 __init__
的显式调用,但 SportsCar
错误地调用了 Vehicle.__init__
。在 FixedSportsCar
中,通过调用 Car.__init__
来修复此问题。
class Vehicle(object):
def __init__(self):
self.mobile = True
class Car(Vehicle):
def __init__(self):
Vehicle.__init__(self)
self.car_init()
#Car.__init__ is missed out.
class SportsCar(Car, Vehicle):
def __init__(self):
Vehicle.__init__(self)
self.sports_car_init()
#Fix SportsCar by calling Car.__init__
class FixedSportsCar(Car, Vehicle):
def __init__(self):
Car.__init__(self)
self.sports_car_init()
参考资料¶
Python 教程:类。
Python 标准库:super。
Artima 开发人员:关于 Python Super 的一些知识。
维基百科:组合优于继承。