【问题标题】:Are methods exactly the same for each instance of a class, or can they be different?类的每个实例的方法是否完全相同,或者它们可以不同?
【发布时间】:2017-04-04 19:50:14
【问题描述】:

我有一段代码可以计算致密恒星的质量和密度分布。其中,每个实例方法都包含一组 if-then 语句 - 根据星型和模型 - 选择适当的数学表达式。我将在底部附加整个更通用的代码,但现在应该有一个精简版。

class Star(object):
    def __init__(self,startype,relativity)
        self.star = startype
        self.r = relativity            

    def integration(self):
        if self.r == 'Galilean': 
           if self.star == 'White Dwarf':
                return simple_expression
           elif self.star == 'Neutron Star':
                return complicated_expression

        elif self.r == 'Einstein':
           ...

'''Make a star'''
neutronEinstein = Star(startype='Neutron',relativity='Einstein')

'''Call integration method'''
Mass = neutronEinstein.integration()

这里的问题是,每次调用集成方法时,都必须评估那些 if-then 语句,这会大大减慢代码的执行速度 - 与更专业的实现相比,代码运行速度更慢一个数量级。我试图将 if-then 语句放在定义之外,就像这样

    if self.r == 'Galilean': 
        if self.star == 'White Dwarf':
            def derivativeOfMass(self):
                return simple_expression

但这不起作用,因为无法识别自我。我发现我可以 - 在某种意义上 - 在我的班级正文中使用 def foo(self): '调用' self 感到困惑,但我不能在那里引用它。虽然我认为如果我说我不能直接在那里引用它的原因是我理解正确,是'self'是尚未创建的类实例的占位符,而不是运行磨机变量?

我很好奇的另一件事是,如果类的每个实例都有自己的一组方法 - 也就是说,如果我做

neutronEinstein = Star(startype='Neutron',relativity='Einstein')
neutronGalilean = Star(startype='Neutron',relativity='Galilean')

Star 类的这两个实例是否都具有完全相同的实例方法“integrate()”,或者它们中的每一个是否有可能 - 本质上 - 有一个单独的 'integrate()'?

所以总结一下,我想做一个让我做的程序

MassE = neutronEinstein.integration()
MassG = neutronGalilean.integration()

在这两种情况下,实例方法 integration() 是不同的。这可能吗?如果是,如何 - 如果不是,是否有另一种直接的方法来避免在每次函数调用时重复 if-then 评估的问题?

您可以在此处找到我的脚本的 python 2.7.6 可运行版本:mainconstants

【问题讨论】:

  • 多态是你要找的,或者在 Python 的情况下更好——鸭子类型。

标签: python class methods instance


【解决方案1】:

您正在使用实例属性来模拟继承,而不是直接使用继承。

class Star(object):
    pass

class Galilean(Star):
    pass

class Einstein(Star):
    pass

class WhiteDwarf(Galilean):
    def integration(self):
        return simple_expression

class NeutronStar(Galilean):
    def integration(self):
        return complicated_expression

'''Make a star'''
neutronEinstein = NeutronStar()

'''Call integration method'''
mass = neutronEinstein.integration()

【讨论】:

  • 所以在您的示例中,我会明确地将最通用的属性放在 Star 类中,将 Einstein 特有的属性放在 Einstein 类中,等等?
  • 没错。此外,如果给定 Start 子类的实例,则任何期望 Star 实例的代码都应该继续工作。
  • 如果 Star 中有一个调用 integration() 方法的方法,这将不起作用。是否有可能反转继承的层次结构?作为参考,您可以在我在 OP 底部链接的脚本中搜索 RK38,该脚本使用 dMdr 和 dPdr。
  • 没关系,我找到了方法。虽然我仍然觉得我不知道我在做什么,所以肯定还有其他方法!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-21
  • 1970-01-01
  • 2015-01-13
  • 1970-01-01
  • 2011-01-03
相关资源
最近更新 更多