Python:当由子类的对象调用时,超类函数如何访问子类变量

问题描述 投票:0回答:1
initialTreeCom=['ADD_CHILD None King_Shan Male','ADD_CHILD None Queen_Anga Female',
                 'AM King_Shan Queen_Anga','ADD_CHILD Queen_Anga Chit Male']

famTree=familyTree.FamiltyTree(initialTreeCom)
result=famTree.excommand('GET_RELATIONSHIP Chit Father')
print(result)

Q1。当我创建从类FamilyTree继承的类Relationships的对象时。 excommand类的称为FamilyTree的函数如何以[

的形式调用父类的函数
getattr(self,arguemen[2].replace('-','_'))(arguemen[1])

但是当我通过使用super而不是self通过gettr函数获取函数引用时,抛出了错误?>>

Q2。超类Father的调用函数Relationships如何使用familyMembers访问子类FamilyTree的变量self.familyMembers

    class Person():
            def __init__(self,mother,name,gender):
                self.name=name
            self.gender=gender
            self.mother=mother
            self.marriedTo=None

        def add_partner(self,marriedTo):
            """
            Assigns passed marriedTo value to marriedTo attribute to calling objects
            """
            if marriedTo != self.marriedTo:
                self.marriedTo=marriedTo

    class FamiltyTree(Relationships):
        familyMembers=OrderedDict()
        def __init__(self,initialTree):        
            for i,line in enumerate(initialTree):
                # print('executing command',i,' : ',line)
                self.excommand(line)

        def excommand(self,command):
            """
            Executes the passed command
            Commands : ADD_CHILD, GET_RELATIONSHIP
            """
            arguemen=command.split()
            if arguemen[0]=='ADD_CHILD':
                # print('adding child')
                p=Person(arguemen[1],arguemen[2],arguemen[3])
                return self.add_Person(p)
            if arguemen[0]=='AM':
                # print('adding married to')
                return self.add_MarriedTo(arguemen[1],arguemen[2])
            if arguemen[0]=='GET_RELATIONSHIP':
                if arguemen[1] not in self.familyMembers:
                    return 'PERSON_NOT_FOUND'
                # print('getting relationship',arguemen[2], 'for : ',arguemen[1])
                **res= getattr(self,arguemen[2].replace('-','_'))(arguemen[1])**
                if res:
                    return ' '.join(res)
                return None

    def add_Person(self,person):
        """
        Adds passed Person to Family members, of calling object of FamiltyTree
        """
        if person.mother!='None' and  person.mother not in self.familyMembers:
            return 'PERSON_NOT_FOUND'
        if isinstance(person,Person) and person.name not in self.familyMembers and (person.mother=='None' or self.familyMembers[person.mother].gender=='Female'):
            self.familyMembers[person.name]=person
            return 'CHILD_ADDITION_SUCCEEDED'
        else:
            return 'CHILD_ADDITION_FAILED'

    def add_MarriedTo(self,person1,person2):
        """
        sets marriedTo Relationship among both passed person objects to each other.
        """
        if person1 in self.familyMembers and person2 in self.familyMembers:
            for key , value in self.familyMembers.items():
                if key==person1:
                    value.add_partner(person2)
                if key==person2:
                    value.add_partner(person1)
            return True
        else:
            return False

class Relationships():

    def Father(self,name):
        """
        Finds Father of passed person name
        """
        if name in self.familyMembers:
            for key , value in self.familyMembers.items():
                if self.familyMembers[self.familyMembers[name].mother].marriedTo==key:
                    return key
        return None

initialTreeCom = ['ADD_CHILD无King_Shan男','ADD_CHILD无Queen_Anga女','AM King_Shan Queen_Anga','ADD_CHILD Queen_Anga Chit Male'] famTree = familyTree.FamiltyTree(...)>

< [
A1。 getattr()正在搜索名称与您传递的字符串相对应的成员。在您的情况下,名称为Father。这是映射用户输入的字符串(在您的情况下为arguemen[2])的便捷方法,以便您可以查看Relationships类中是否存在该关系的实现。

这很聪明。现在,您可以将其他关系的实现添加到Relationship类,而无需修改GET_RELATIONSHIP的实现。

或者,您可以将Father实现为:

if arguemen[2] == 'Father': res = self.Father(arguemen[1])

但是您必须对要实现的每种类型的关系都执行此操作(例如,'Brother,Cousin`)。

Relationships这个类使您可以轻松地通过走动家族树来实现个人关系。 Father()实现是一个很好的例子。

A2。因为当Python遇到self.x时,它首先在当前类中搜索数据属性x,如果找不到,则继续搜索类属性x,并将其用于对self.x的后续操作]。在您的情况下,familyMembers是类属性,它恰好位于超类Relationships中。 super仅查看数据成员。

关于类和实例属性here进行了精彩的讨论>

python inheritance parent-child subclass superclass
1个回答
0
投票
A1。 getattr()正在搜索名称与您传递的字符串相对应的成员。在您的情况下,名称为Father。这是映射用户输入的字符串(在您的情况下为arguemen[2])的便捷方法,以便您可以查看Relationships类中是否存在该关系的实现。

这很聪明。现在,您可以将其他关系的实现添加到Relationship类,而无需修改GET_RELATIONSHIP的实现。

© www.soinside.com 2019 - 2024. All rights reserved.