• python中的关联关系


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

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

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

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

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

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

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

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

    那有什么解决方法么?

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

    如下代码示:

    1. # A sample class example :
    2. class People:
    3. def __init__(self,pname,page,p_lover_parterner=None):
    4. self.name = pname
    5. self.age = page
    6. self.lover_parterner = p_lover_parterner
    7. def Info(self):
    8. print(self.name,self.age,"对象名字是:",self.lover_parterner.name)
    9. AA = People("AA",22)
    10. BB = People("BB",23)
    11. AA.lover_parterner = BB #必须要双向绑定,AA绑定BB一次
    12. BB.lover_parterner = AA #必须要双向绑定,BB绑定AA一次
    13. AA.Info()
    14. 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。

    那么实现代码如下:

    1. # A sample class example :
    2. class People:
    3. def __init__(self,pname,page):
    4. self.name = pname
    5. self.age = page
    6. def Info(self):
    7. print(self.name,self.age)
    8. class Team_Relation:
    9. def __init__(self):
    10. self.team_list = []
    11. def insert_new_people( self , new_peo_obj , old_peo_obj):
    12. tag = 0
    13. for team_item in self.team_list :
    14. if old_peo_obj in team_item :
    15. tag = 1
    16. team_item.append(new_peo_obj)
    17. print("此时的情况是新人",new_peo_obj.name,"找到了队伍成功加入老同志",old_peo_obj.name,"所在的队伍")
    18. if tag==0:
    19. newteam = [new_peo_obj,old_peo_obj]
    20. self.team_list.append(newteam)
    21. print("此时的情况是新人",new_peo_obj.name,"发现老同志",old_peo_obj.name,"不属于任何队伍,于是他俩自己组成了一个新队伍")
    22. def team_Info(self):
    23. for team_item in self.team_list:
    24. print( [ peo_obj.name for peo_obj in team_item ] ) ## [ peo_obj.name for peo_obj in team_item ] 是一种叫列表解析式的语法糖
    25. # 假设AA、BB是新人 , AA要拜师MM,即加入MM队伍 ; BB要拜师NN,即加入NN队伍 ; CC、DD要拜师BB,即加入BB队伍
    26. # 假设现在队伍中就只有MM
    27. AA = People("AA",22)
    28. BB = People("BB",23)
    29. CC = People("CC",21)
    30. DD = People("DD",26)
    31. MM = People("MM",22)
    32. NN = People("NN",23)
    33. team_relation_set = Team_Relation()
    34. team_relation_set.team_list.append([MM]) # 对应实现假设:现在队伍中就只有MM,他自成一个team
    35. team_relation_set.insert_new_people(AA,MM)
    36. print('--'*50)
    37. team_relation_set.insert_new_people(BB,NN)
    38. print('--'*50)
    39. team_relation_set.insert_new_people(CC,BB)
    40. print('--'*50)
    41. team_relation_set.insert_new_people(DD,BB)

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

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

    即:

    1. # A sample class example :
    2. class People:
    3. def __init__(self,pname,page,team_relation_obj):
    4. self.name = pname
    5. self.age = page
    6. self.team_relation = team_relation_obj
    7. def Info(self):
    8. print(self.name,self.age)
    9. class Team_Relation:
    10. def __init__(self):
    11. self.team_list = []
    12. def insert_new_people( self , new_peo_obj , old_peo_obj):
    13. tag = 0
    14. for item_team in self.team_list :
    15. if old_peo_obj in item_team :
    16. tag = 1
    17. item_team.append(new_peo_obj)
    18. print("此时的情况是新人",new_peo_obj.name,"找到了队伍成功加入老同志",old_peo_obj.name,"所在的队伍")
    19. if tag==0:
    20. newteam = [new_peo_obj,old_peo_obj]
    21. self.team_list.append(newteam)
    22. print("此时的情况是新人",new_peo_obj.name,"发现老同志",old_peo_obj.name,"不属于任何队伍,于是他俩自己组成了一个新队伍")
    23. def team_Info(self):
    24. """将所有的team他们中的成员全部输出"""
    25. for item_team in self.team_list:
    26. print( [ peo_obj.name for peo_obj in item_team ] ) ## [ peo_obj.name for peo_obj in team_item ] 是一种叫列表解析式的语法糖
    27. def judge_people_in_which_team(self,peo_obj):
    28. """判断peo_obj是在哪个team中,并打印team的信息"""
    29. tag = 0
    30. for item_team in self.team_list :
    31. if peo_obj in item_team :
    32. print(peo_obj.name,"属于一个team中,该team的成员有:",[peo_item.name for peo_item in item_team] )
    33. tag = 1
    34. break
    35. if tag == 0 :
    36. print("这个人不在任何的项目组中阿")
    37. # 假设AA、BB是新人 , AA要拜师MM,即加入MM队伍 ; BB要拜师NN,即加入NN队伍 ; CC、DD要拜师BB,即加入BB队伍
    38. # 假设现在队伍中就只有MM
    39. team_relation_set = Team_Relation() # 那么这个时候就得先对关系进行实例化了
    40. AA = People("AA",22,team_relation_set)
    41. BB = People("BB",23,team_relation_set)
    42. CC = People("CC",21,team_relation_set)
    43. DD = People("DD",26,team_relation_set)
    44. MM = People("MM",22,team_relation_set)
    45. NN = People("NN",23,team_relation_set)
    46. qqqqq = People("qqqqq",26,team_relation_set)
    47. # --------------------------------------------------------------------------
    48. team_relation_set.team_list.append([MM]) # 对应实现假设:现在队伍中就只有MM
    49. team_relation_set.insert_new_people(AA,MM)
    50. team_relation_set.insert_new_people(BB,NN)
    51. team_relation_set.insert_new_people(CC,BB)
    52. team_relation_set.insert_new_people(DD,BB)
    53. print('--'*50)
    54. # --------------------------------------------------------------------------
    55. AA.team_relation.judge_people_in_which_team(AA)
    56. CC.team_relation.judge_people_in_which_team(CC)
    57. 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类中的函数

  • 相关阅读:
    Python连接SQL SEVER数据库全流程
    C++入门之命名空间详解
    TDengine 3.0 存储引擎升级之路
    如何将微软 Office 宏转换为 ONLYOFFICE 宏
    SQLite3数据类型
    Maven 没使用本地依赖,报错依赖找不到 Failure to find xxx
    深度强化学习笔记
    ECCV2022 | 人大提出轻量级基于注意力的特征融合机制,在多个公开数据集上有效!代码已开源!
    第七章 块为结构建模 P5|系统建模语言SysML实用指南学习
    什么是低代码开发平台?有什么优势?
  • 原文地址:https://blog.csdn.net/qq_41764621/article/details/125898856