首页 > 解决方案 > 派生类的存在是否会修改基类,即使派生类从未使用过?

问题描述

我有一个基类Sample和一个派生类SignalSample,这两个类的代码通常位于同一个文件Sample.py中。

我以通常的方式将这些类导入到我的主脚本中:from Sample import Sample, SignalSample

在寻找其中一个类中的错误时,我注意到一些不寻常的行为:删除SignalSample派生类的代码会改变Signal基类的行为。

所以我的问题是,即使派生类从未实例化,派生类的存在能否改变基类?

具体来说,我尝试了以下组合。

  1. Sample和的代码SignalSample 都在Sample.py. from Sample import Sample, SignalSample在我的主脚本中用于加载这些类。Sample 对象被实例化,没有SignalSample对象被实例化,代码就在那里并且未被使用。在这种情况下,我会收到一个错误,我将其称为“类型 1”。
  2. 删除SignalSampleinside的代码Sample.py,并删除 ... import SignalSample语句。在这种情况下,我得到一个不同的错误,我称之为“类型 2”。

请注意,我不认为错误来自类本身(尽管它们可能是),更有趣的是我发现代码的行为似乎发生了变化,因为有一个继承的类,即使那个类没有使用。

这是我的设置的精简示例,请注意,这不是我的错误来源的 MWE,因为目前我不知道它来自哪里,所以我什至无法缩小范围. 这不是我正在寻找的错误的解决方案,只是有关这种看似奇怪的类继承行为的更多信息。

# file Sample.py
class Sample:
   def __init__(self):
      self._tfile = None
      self._filepath = None

   def calculate_filepath(self):
      return "my/file/path"

   __calculate_filepath = calculate_filepath # private copy

   def get_histogram(self, histogram_name):
      if not self._filepath:
         self._filepath = self.calculate_filepath()
      if not self._tfile:
         from ROOT import TFile # this is a special filetype 
         self._tfile = TFile.Open(self._filepath, "READ")

      histo = self._tfile.Get(histogram_name)
      histo.SetDirectory(0)
      self._tfile.Close()
      return histo

class SignalSample(Sample):
   def __init__(self):

      # Inherit
      Sample.__init__(self)

      self._filepath = self.calculate_filepath()

   def calculate_filepath(self):
      # Overloaded version of the function in Sample
      return "my/very/special/filepath"

请注意,我选择调用calculate_filepath内部方法get_histogram是因为我想避免可能与派生类发生命名空间冲突。这也是为什么我尝试使用命名空间修饰使方法“私有”。这也是我TFile在方法中打开特殊文件的原因get_histogram,尽管很高兴我可以Close在同一个函数中也使用这个文件。也许这不是正确的用法,也许这与我的问题的根源有关?

标签: pythonpython-2.7polymorphism

解决方案


get_histogram如果不止一次调用它,它看起来可能会损坏。您将打开的文件分配给实例(on self._tfile),然后在返回之前将其关闭......这意味着下次调用该方法not self._tfile时可能会(*)评估为False,这意味着您然后尝试调用Get已关闭的文件。如果您使用的是健全的库,这可能会抛出一个很好的错误告诉您这一点,但我看到您正在使用 ROOT,所以谁知道会发生什么:)

可能最简单的方法是不要将文件存储在 上Sample,而是在get_histogram调用时打开文件?

(*) 隐含的粗鲁有时值得避免。特别是当您真正想要检查的是某事是否为无时,更喜欢写作if x is None:https://legacy.python.org/dev/peps/pep-0008/#programming-recommendations

顺便说一句,在这个例子中,__calculate_filepath = calculate_filepath # private copy没有做任何事情,因为你从来没有真正使用过它。


推荐阅读