python面向对象OOP编程(三)-- 同类 不同实例 之间的关联关系

当一个类有多个实例,但是在实例之间有着相互的关联关系,此时,不建议在实例中新增一个成员属性来描述这种关联关系

据一个实际场景来帮助理解:People类有两个实例:AA和BB,AA是男的,BB 是女的,BB 是AA 的女朋友。它们之间有个情侣关系。

我想要描述这种人与人之间的情侣关系:那么,如果我采用的实现方法是向People类中添加一个成员属性lover_parterner。那么,会出现以下几个问题:

(1)如果一个人,他没有对象,那么这个属性的值如何初始化

----这个问题好解决,我们在成员属性中将lover_parterner的初始值设置为None就可以了

(2)现在假设这个人是有lover的,那么应该如何在初始化的时候就将lover_parterner属性的值赋为其lover这个实例呢?

----这是没有办法解决的事情。原因见下述代码

# A sample class example :

class People:
    def __init__(self,pname,page,p_lover_parterner=None):
        self.name = pname
        self.age = page
        self.lover_parterner = p_lover_parterner  
    def Info(self):
        print(self.name,self.age,self.lover_parterner)
    
AA = People("AA",22,???)    #此处按照逻辑,我本应该将 BB 实例作为函数的第三个参数,但,现在BB实例还没有被定义,无法作为参数赋值,尽管AA和BB已经是情侣关系
BB = People("BB",23,AA)

那有什么解决方法么?

有的,就是很麻烦:由于我们之前给单身的人们一条活路:将lover_parterner这个成员属性的初始值定为了None。所以现在,我们即使已知AA和BB 是情侣关系,我们依旧在实例化AA和BB 的时候,第三个参数不填写,使lover_parterner值为None。然后,用语句在后面显示地将这两个实例之间的lover_parterner属性值设为对方:

如下代码示:

# A sample class example :

class People:
    def __init__(self,pname,page,p_lover_parterner=None):
        self.name = pname
        self.age = page
        self.lover_parterner = p_lover_parterner
    def Info(self):
        print(self.name,self.age,"对象名字是:",self.lover_parterner.name)

AA = People("AA",22)
BB = People("BB",23)

AA.lover_parterner = BB    #必须要双向绑定,AA绑定BB一次
BB.lover_parterner = AA    #必须要双向绑定,BB绑定AA一次

AA.Info()
BB.Info()

这样就解决了。

但是这种解决方式,也引发了新的问题:试想一种情况,如果现在People的实例AA、BB、CC等多个人之间是同一个team的关系。那么,此时,难道要再设立一个数据结构为列表的 team_parterner 成员属性,每次这个team新来一个新人,之前的老人儿就都将自己的team_parterner 进行增加:把这个新人加入到自己的team_parterner列表中去么?这样一来是操作繁琐(大量的重复劳动),二来是:万一哪个 老人儿 漏掉了谁没有添加进自己的列表,这种就会造成不一致。

那么如何解决这种 同类实例 之间的 关联关系 呢 ?

---- 新建立一个类,用这个类生成的实例来维护同类实例之间的关联关系

假设AA、BB是新人 , AA要拜师MM,即加入MM队伍 ; BB要拜师NN,即加入NN队伍 ; CC、DD要拜师BB,即加入BB队伍。现假设现在队伍中就只有MM。

那么实现代码如下:

# A sample class example :

class People:
    def __init__(self,pname,page):
        self.name = pname
        self.age = page

    def Info(self):
        print(self.name,self.age)

class Team_Relation:
    def __init__(self):
        self.team_list = []
    def insert_new_people( self , new_peo_obj , old_peo_obj):
        tag = 0
        for team_item in self.team_list :
            if  old_peo_obj in team_item :
                tag = 1
                team_item.append(new_peo_obj)
                print("此时的情况是新人",new_peo_obj.name,"找到了队伍成功加入老同志",old_peo_obj.name,"所在的队伍")

        if tag==0:
            newteam = [new_peo_obj,old_peo_obj]
            self.team_list.append(newteam)
            print("此时的情况是新人",new_peo_obj.name,"发现老同志",old_peo_obj.name,"不属于任何队伍,于是他俩自己组成了一个新队伍")

    def team_Info(self):
        for team_item in self.team_list:
            print( [ peo_obj.name  for peo_obj in team_item ] )    ## [ peo_obj.name  for peo_obj in team_item ] 是一种叫列表解析式的语法糖


# 假设AA、BB是新人 , AA要拜师MM,即加入MM队伍 ; BB要拜师NN,即加入NN队伍 ; CC、DD要拜师BB,即加入BB队伍
# 假设现在队伍中就只有MM

AA = People("AA",22)
BB = People("BB",23)
CC = People("CC",21)
DD = People("DD",26)

MM = People("MM",22)
NN = People("NN",23)

team_relation_set = Team_Relation()

team_relation_set.team_list.append([MM])    # 对应实现假设:现在队伍中就只有MM,他自成一个team
team_relation_set.insert_new_people(AA,MM)
print('--'*50)
team_relation_set.insert_new_people(BB,NN)
print('--'*50)
team_relation_set.insert_new_people(CC,BB)
print('--'*50)
team_relation_set.insert_new_people(DD,BB)





但没完,确实不再需要冗余的的处理了对于同项目组的人员添加了,但是,当我想通过一个people实例来去查询自己属于那个组,组里还有哪些人的时候,这种时候,上述的代码就不能做得到

解决办法是:将关系类Team_Relation的实例 team_realtion_obj 作为People类中的一个成员属性

即:

# A sample class example :

class People:
    def __init__(self,pname,page,team_relation_obj):
        self.name = pname
        self.age = page
        self.team_relation = team_relation_obj

    def Info(self):
        print(self.name,self.age)

class Team_Relation:
    def __init__(self):
        self.team_list = []
    def insert_new_people( self , new_peo_obj , old_peo_obj):
        tag = 0
        for item_team in self.team_list :
            if  old_peo_obj in item_team :
                tag = 1
                item_team.append(new_peo_obj)
                print("此时的情况是新人",new_peo_obj.name,"找到了队伍成功加入老同志",old_peo_obj.name,"所在的队伍")

        if tag==0:
            newteam = [new_peo_obj,old_peo_obj]
            self.team_list.append(newteam)
            print("此时的情况是新人",new_peo_obj.name,"发现老同志",old_peo_obj.name,"不属于任何队伍,于是他俩自己组成了一个新队伍")

    def team_Info(self):
        """将所有的team他们中的成员全部输出"""
        for item_team in self.team_list:
            print( [ peo_obj.name  for peo_obj in item_team ] )    ## [ peo_obj.name  for peo_obj in team_item ] 是一种叫列表解析式的语法糖

    def judge_people_in_which_team(self,peo_obj):
        """判断peo_obj是在哪个team中,并打印team的信息"""
        tag = 0
        for item_team in self.team_list :
            if peo_obj in item_team :
                print(peo_obj.name,"属于一个team中,该team的成员有:",[peo_item.name for peo_item in item_team] )
                tag = 1
                break

        if tag == 0 :
            print("这个人不在任何的项目组中阿")





# 假设AA、BB是新人 , AA要拜师MM,即加入MM队伍 ; BB要拜师NN,即加入NN队伍 ; CC、DD要拜师BB,即加入BB队伍
# 假设现在队伍中就只有MM

team_relation_set = Team_Relation()         # 那么这个时候就得先对关系进行实例化了

AA = People("AA",22,team_relation_set)
BB = People("BB",23,team_relation_set)
CC = People("CC",21,team_relation_set)
DD = People("DD",26,team_relation_set)

MM = People("MM",22,team_relation_set)
NN = People("NN",23,team_relation_set)

qqqqq = People("qqqqq",26,team_relation_set)

# --------------------------------------------------------------------------

team_relation_set.team_list.append([MM])    # 对应实现假设:现在队伍中就只有MM

team_relation_set.insert_new_people(AA,MM)
team_relation_set.insert_new_people(BB,NN)
team_relation_set.insert_new_people(CC,BB)
team_relation_set.insert_new_people(DD,BB)
print('--'*50)

# --------------------------------------------------------------------------

AA.team_relation.judge_people_in_which_team(AA)
CC.team_relation.judge_people_in_which_team(CC)
qqqqq.team_relation.judge_people_in_which_team(qqqqq)

上述代码有两个要点要注意:

首先是,由于People类实例化时需要Team_Realtion的实例作为参数,那么肯定得先对关系进行实例化了。

其次是,对于从People实例中去判断该实例是否属于team等 需要通过People实例 对 关系 进行操作 的函数 一般放在关系类中进行定义(比如本例中的

judge_people_in_which_team() 这个函数在类Team_Realtion定义 )

【Note】这里补充一个可能存在的疑问:为啥代码里AA.team_relation.judge_people_in_which_team(AA) 明明是AA实例调用,但还要传个参数 AA呢?

因为:AA调用的是team_relation这个类属性(这个 AA 的 team_relation 类属性呢又是一个Team_Realtion实例)。然后,Team_Realtion实例去调用定义在Team_Realtion类中的函数,那这肯定需要传入参数peo_obj呀,毕竟这个函数是Team_Realtion类中的函数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值