You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实例化Epic类时未生成默认对象而是复制父对象属性问题

问题描述
  • 我是Python新手,有一个继承自V1Superclass的Epic类,该类可将自身实例作为子对象存入Children列表。
  • 在Python控制台直接创建Epic实例(如a = V1.Epic()、b = V1.Epic())时,实例能正确初始化默认值;但在populateChildren方法中实例化Epic对象时,新创建的childEpic并非默认实例,而是复制了父对象(self)的所有属性。
  • 虽然执行self is childEpic返回False(说明并非同一对象),但此行为不符合预期。尝试新增addChild函数在父对象作用域外实例化,问题仍存在。
相关代码
class Epic(V1Superclass):
    Type = 'Epic'
    Children = []
    ParentAssetID = []

    @classmethod
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            if key == 'Name':
                self.Name = value
            elif key == 'Description':
                self.Description = value
            elif key == 'Super':
                self.Super = value
            elif key == 'Scope':
                self.Scope = value
        if not bool(self.Super):
            self.Super = None
        if not bool(self.Scope):
            self.Scope = 445082

    def populateChildren(self,env,key):
        children = V1.utl.getChildren(env,key,'Epic',self.AssetID)
        for child in children:
            oid_type = child['_oid'].split(':')[0]
            if oid_type == 'Story':
                print('Got another backlog child')
            elif oid_type == 'Defect':
                print('Got another Defect child')
            elif oid_type == 'Epic':
                childEpic = V1.Epic()
                self.Children.append(childEpic)
解决方法

1. 修复类属性共享问题

Children和ParentAssetID是类属性,所有Epic实例会共用同一个列表对象。当你在父实例中添加子对象到Children,其他实例的Children也会同步变化,看起来像是子对象继承了父属性,实际是类属性被共享导致的错觉。

修复方式:把这两个属性移到__init__方法内,改为实例属性,每个实例都会拥有独立的列表:

def __init__(self, **kwargs):
    # 初始化实例专属的列表
    self.Children = []
    self.ParentAssetID = []
    # 原有初始化逻辑...

2. 移除错误的@classmethod装饰器

__init__方法是实例初始化方法,不该添加@classmethod装饰器。这个装饰器会把方法的第一个参数从实例对象(self)变成类对象(cls),导致你的初始化逻辑错误地操作了类的属性状态,进而引发实例化时的属性复用问题。

修复方式:直接去掉__init__上的@classmethod:

def __init__(self, **kwargs):
    # 初始化逻辑...

可选:简化__init__逻辑

可以用kwargs.get()简化属性赋值代码,让逻辑更清晰:

def __init__(self, **kwargs):
    self.Children = []
    self.ParentAssetID = []
    self.Name = kwargs.get('Name')
    self.Description = kwargs.get('Description')
    self.Super = kwargs.get('Super') or None
    self.Scope = kwargs.get('Scope') or 445082

内容的提问来源于stack exchange,提问作者motorhead9999

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 15:00:53