【问题标题】:global name self not defined in inherited class全局名称 self 未在继承的类中定义
【发布时间】:2018-01-22 21:33:47
【问题描述】:

我在python中定义了一个抽象基类:

class calculator:
    __metaclass__ = ABCMeta

    @abstractmethod
    def __init__(self, fileName):
        path = './cartesians/'
        onlyFiles = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
        for elem in list(onlyFiles):
            test = elem.split('.')[0]
            if test != fileName.split('.')[0]:
                onlyFiles.remove(elem)
        self.onlyFiles = onlyFiles
        self.onlyFiles.sort()

    @abstractmethod
    def optimize(self):
        pass

mopac 类继承自计算器类:

from calculator import *

class mopac(calculator):

     def __init__(self, fileName):
        self.test = "test"
        super(mopac, self).__init__(fileName)

    def optimize(calculator):
        print self.test
        for file in self.onlyFiles:
           do stuff

在 main.py 中,我有:

from mopac import *

calc = mopac(inFile)
calc.optimize()

当我运行代码时,它告诉我:

File "main.py", line 50, in main
    calc.optimize()
  File "path/mopac.py", line 24, in optimize
    print self.test
NameError: global name 'self' is not defined

我不明白为什么它在这里将 self 视为变量/属性。有人可以帮忙吗?如果我删除“print self.test”,那么它会给我同样的错误“self is not defined” with self.onlyFiles。

【问题讨论】:

    标签: python class oop attributes self


    【解决方案1】:

    在 Python 中,您应该指定 self 作为定义的第一个形参。在您的代码中,calculator 是您的第一个形式参数,因此当它作为对象/实例方法调用时,它采用实例的值并且没有可访问的形式参数 self(导致报告的语法错误):

    def optimize(self):
        print self.test
        for file in self.onlyFiles:
           do stuff
    

    【讨论】:

    • 如果我这样做,它会给出关于传递给优化函数的参数数量不正确的错误。由于优化是在抽象类中定义的,我不需要将 self 作为参数传递。
    • 那是因为您没有为calculator 传递实际参数,这也是您原始代码中的问题,除了calculator 被分配了通常分配给的值self,所以您对optimize 的调用没有触发错误(除了self 不存在,正如您所料)。
    • 由于您没有使用形式参数calculator,并且optimize 与基类声明不匹配,因此我将示例更改为简单地将calculator 重命名为self
    【解决方案2】:
      def optimize(calculator):
            print calculator.test
            for file in calculator.onlyFiles:
               do stuff
    

    每个类方法(包括 init)的第一个参数始终是对当前类实例的引用。按照惯例,这个参数总是命名为 self。在init方法中,self指的是新创建的对象;在其他类方法中,它指的是被调用方法的实例。

    在这种情况下,您将“self”变量重命名为“calculator”。将其更改为 self 或将 self 重命名为计算器。

    More info

    Other that may help you

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-04
      • 2015-12-22
      • 2014-04-18
      • 2015-08-08
      • 2011-04-27
      • 2013-09-04
      • 2015-02-26
      • 2016-09-11
      相关资源
      最近更新 更多