【问题标题】:Python, Referencing child attributes and methods in base class (and vice versa) there has to be a better wayPython,在基类中引用子属性和方法(反之亦然)必须有更好的方法
【发布时间】:2013-11-03 16:34:18
【问题描述】:

我有一个由多个子类继承的基类。此基类有一个方法 calc_func(self),它在子类中使用统一命名的方法 func(self)。这可行,但如果代码变得越来越复杂,这种“架构”将很难遵循。

# Base class
class base():
    x = 12  
    def calc_func(self):
        for i in range(1,4):
            self.y += self.func() 
            # neither y nor func() are defined here so
            # it is hard to know where they came from


# Child class 1
class child1(base):
    y = 10
    def __init__(self):
        pass

    def func(self):   # method used in base class
        self.x += self.y
        print self.x
        return self.x
        # x was not defined here so it is
        # hard to know where it came from

# Child class 2
class child2(base):
    y = 15
    def __init__(self):
        pass

    def func(self):   # method used in base class
        self.x *= self.y
        print self.x
        return self.x
        # x was not defined here so it is
        # hard to know where it came from

test1 = child1()  # Create object
test1.calc_func() # Run method inherited from base class


test2 = child2()  # Create another object
test2.calc_func() # Run method inherited from base class

这个想法是将通用代码抽象到基类中,但这似乎不是正确的做法。也许这可以通过使用引用其特定来源类的方法和属性的命名约定来更容易理解?也许完全不同的架构?任何建议将不胜感激。

【问题讨论】:

  • 您可以使用abc.ABCMeta 元类使Base 类抽象,然后在Base 类中实现func 并用@abstractmethod 标记它。或者,简单地将def func(self): raise NotImplementedError() 放在基类中可以提供一些关于func 来自何处的线索。通过这种方式,您还可以向抽象 func 添加一些文档,说明它应该具有的属性,以便用户可以安全地派生该类并正确实现功能。
  • 这实际上只是记录那些所谓的方法是什么的问题。这就是抽象方法的优势,你可以添加一个文档字符串,它会显示在基类和非覆盖子类中,告诉实现者发生了什么。
  • 谢谢,我会试试这些建议

标签: python class inheritance structure base


【解决方案1】:

这个基类有一个方法,calc_func(self),它在子类中使用统一命名的方法,func(self)。这可行,但如果代码变得越来越复杂,这种“架构”将很难遵循。

不,这正是面向对象多态应该如何工作的。你已经做对了!

您说这似乎很难理解,但不清楚您为什么认为这很困难。您可能唯一能做的就是 (a) 将基类标记为 abstract (b) 让子类应该提供的所有方法都存在于基类上,但只让它们引发 NotImplementedError

【讨论】:

  • 感谢您的评论。我认为如果基类和子类的长度达到数百行并且您进行多重继承,那么您最终可能会得到基类和子类之间关系的蜘蛛网,这可能会给调试带来相当大的挑战。话虽如此,我会尝试你的建议。在 (b) 点中,您的意思是:CHILD 类应该提供的所有方法都存在于基类中吗...?
  • @user2923409 是的,我的回答有误。您的基类不应有数百行长;即使您的子类中的方法很长,也没关系。复杂性来自于数百种方法,您应该避免使用这些方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 2018-05-19
  • 1970-01-01
  • 2012-09-03
  • 1970-01-01
相关资源
最近更新 更多