CodeQL 文档

对象初始化期间缺少对 __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

单击以查看 CodeQL 代码库中的查询

与 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()
        

参考资料

  • ©GitHub, Inc.
  • 条款
  • 隐私