【问题标题】:Why is attribute being inherited across classes in Python?为什么在 Python 中跨类继承属性?
【发布时间】:2012-06-19 23:53:26
【问题描述】:

我显然在学习如何正确使用类时遇到了一些麻烦。我希望下面的代码循环遍历一组文件(确实如此),将元素添加到集合中(确实如此),并在它移动到新文件时重新开始集合(它没有)。我破解下面的代码的方式,我希望它每次都为file.terminals 返回一个空集,因为我相信每个集都是SrcFile 类的新实例的唯一属性。显然,我错了。实际发生的情况是,第一个文件创建的终端集对于列表中的所有后续文件都保留(并添加到),尽管其他属性(例如file.namefile.seqlength())会随着文件而适当更改。有人可以解释为什么它会以这种方式工作以及如何创建我期望的行为吗?提前感谢您对初学者的无知的耐心。

class SrcFile:
   terminals = set([])
   def __init__(self, which):
      self.name = which
   def seqlength(self):
      with open(self.name) as file:
         linecounter = 0
         for line in file:
            linecounter += 1
            if linecounter == 3:
               return int(line.split()[0])
               break

class Record(SrcFile):
   def terminal(self):
      record = self.name
   def terminal(self):
      record = self.name
      return record.split()[0]

for f in files:
   file = SrcFile(f)
   print(file.name, file.seqlength(), file.terminals)

   with open(f) as f:
      recordline = re.compile(r"^([A-Z]{5})\s{3}")
      for line in f:
         if recordline.match(line):
            record = Record(line)
            if record.terminal() in file.terminals:
               pass
            else:
               file.terminals.add(record.terminal())

【问题讨论】:

    标签: python class attributes


    【解决方案1】:

    您是在类声明中定义terminals,而不是在为类的每个新实例执行的__init__ 函数中。

    基本上,terminals 是针对整个类初始化的,而不是针对类的每个实例:

    >>> SrcFile.terminals
    set([])
    

    注意我运行的是SrcFile.terminals,而不是SrcFile().terminals,这意味着SrcFile 是对类的引用,而不是类的实例。

    您将类似的变量放在__init__ 函数中,以使它们特定于实例:

    class SrcFile(object):
      def __init__(self, which):
        self.name = which
        self.terminals = set([])
    

    【讨论】:

    【解决方案2】:

    通过在类本身中定义terminals = set([]),它在定义类时创建一次,而不是在创建实例时创建。

    为避免这种情况,请将其删除并将以下内容添加到您的 __init__ 方法中:

    self.terminals = set()
    

    【讨论】:

    • 谢谢!那解决了它。我非常感谢这个论坛对我们这些刚刚起步的人的耐心。
    • 知道了……要学的东西太多了。接受提交的第一个正确答案并签字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-02
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 2016-07-08
    • 2010-09-17
    相关资源
    最近更新 更多