Skip to main content
 首页 » 编程设计

Python:为什么我使用 super() 而不是使用显式父类(super class)名称时会出现异常

2025年05月04日23zhoujg

当我尝试使用 super() 访问基类的属性时出现异常,但当我显式使用基类名称时却没有。这是派生类:

from CPSA_TransactionLogOutSet import CPSA_TransactionLogOutSet 
 
class CPSA_TransactionFailureSet(CPSA_TransactionLogOutSet): 
    def __init__(self, connection, failedTransactionKey): 
        super().__init__(connection) 
        CPSA_TransactionLogOutSet.C_TRANS_TYP = "TRANS_FAIL" 
        super().C_TRANS_TYP = "TRANS_FAIL" 
        super().DefaultTableName = 'CPSA_TRANSACTION_LOG_IN' 
        super()._keyFields.append('J_TRANS_SEQ') 

但是尝试创建一个实例会引发一个AttributeError异常:

AttributeError: 'super' object has no attribute 'C_TRANS_TYP' 

基类由一个 __init__() 方法和一组属性组成,这里只显示其中一个:

class CPSA_TransactionLogOutSet(Recordset): 
    def __init__(self, connection): 
        super().__init__(connection) 
        self.DefaultTableName = 'CPSA_TRANSACTION_LOG_OUT' 
 
    @property 
    def C_TRANS_TYP(self): 
        return self.GetValue('C_TRANS_TYP') 
    @C_TRANS_TYP.setter 
    def C_TRANS_TYP(self, value): 
        self.SetValue('C_TRANS_TYP', value) 

为什么我不能使用 super() 访问 C_TRANS_TYP 属性?

请您参考如下方法:

您根本不需要使用 super() 因为当前类没有覆盖。描述符将绑定(bind)到 self 而无需 super()。这同样适用于 self 的其他属性:

def __init__(self, connection, failedTransactionKey): 
    super().__init__(connection) 
    self.C_TRANS_TYP = "TRANS_FAIL" 
    self.DefaultTableName = 'CPSA_TRANSACTION_LOG_IN' 
    self._keyFields.append('J_TRANS_SEQ') 

super() 只需要访问无法通过 self 访问的描述符。 正常访问路径(通过实例)在这里就足够了。

super() 不能用于在赋值或 del obj.attr 语句中绑定(bind)数据描述符,因为 super()对象不实现 __set__ 或 __delete__。换句话说,使用 super().attribute 仅适用于读取 属性,绝不能用于写入或删除。

设置 CPSA_TransactionLogOutSet.C_TRANS_TYP 也是不正确的; 替换类上的描述符对象。通过执行该行,您从类层次结构中完全删除了描述符,因此 self.C_TRANS_TYP 和 super().C_TRANS_TYP 都不会触发 property 你之前定义过。