【问题标题】:Python 3 Accessing variable result from another ClassPython 3 访问另一个类的变量结果
【发布时间】:2014-10-12 20:56:50
【问题描述】:

我有一个变量更新的小问题。

我的变量在我的第一个函数中声明为 self.TestVar = 0 那么如果某个计数 ==2 self.TestVar = 2

在第二个函数中(在同一个类中),但从另一个类中调用,我想返回 self.TestVar。没办法。

AttributeError: 'ThndClass' object has no attribute 'TestVar'

我肯定不是在做好方法,我想要的只是从我的其他类访问 self.TestVar = 2 就是这样,但我在 Python 中找不到合适的方法。 看起来我的问题是我在“if”语句中得到了 self.TestVar = 2,这使它存在于另一个范围内(或者我可能错了)。

import sys
from PIL import Image
from PyQt4 import QtCore, QtGui


class MainWindow(QtGui.QWidget):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.initUI()

    def initUI(self):

        self.TestVar = 0
        self.TheCount = 2
        if self.TheCount ==2:
            self.TestVar = 2
        ThndClass()




    def Getit(self):
        print("called correctly")
        print(self.TestVar)
        return  self.TestVar



def main():

    app = QtGui.QApplication([])
    mw = MainWindow()
    sys.exit(app.exec_())


class ThndClass(QtGui.QWidget):
    def __init__(self):
        super(ThndClass, self).__init__()
        self.initUI2()

    def initUI2(self):
        print("Class Called")
        print(MainWindow.Getit(self))

if __name__ == '__main__':
    main()

如果我删除 2nd Class 呼叫:

import sys
from PIL import Image
from PyQt4 import QtCore, QtGui




class MainWindow(QtGui.QWidget):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.initUI()

    def initUI(self):

        self.TestVar = 0
        self.TheCount = 2
        if self.TheCount ==2:
            self.TestVar = 2
        self.Getit()




    def Getit(self):
        print("called correctly")
        print(self.TestVar)
        return  self.TestVar



def main():

    app = QtGui.QApplication([])
    mw = MainWindow()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

这可以正常工作,但我希望能够从另一个类调用 def Getit() 并获得我的结果。或者干脆从我的其他班级直接访问 self.TestVar。

【问题讨论】:

  • 其实这是我实际代码的最小示例。

标签: function class variables python-3.x scope


【解决方案1】:

当你打电话时

MainWindow.Getit(self)

ThndClass.initUI2 中,当MainWindowThndClass 具有 相同的属性时,它们可以互换处理。这是一个实际的最小示例:

class Parent():

    def __init__(self):
        pass


class Child1(Parent):

    def __init__(self):
        super().__init__()
        self.foo = "foo"

    def method(self): 
        print(type(self))
        print(self.foo)


class Child2(Parent):

    def __init__(self):
        super().__init__()
        self.bar = "bar"


c1 = Child1()
Child1.method(c1) # pass Child1 instance to Child1 instance method
c2 = Child2()
Child1.method(c2) # pass Child2 instance to Child1 instance method

和完整的输出:

<class '__main__.Child1'> # gets a Child1 instance
foo # first call succeeds
<class '__main__.Child2'> # gets a Child2 instance (which doesn't have 'foo')
Traceback (most recent call last):
  File "C:/Python34/so.py", line 25, in <module>
    Child1.method(c2)
  File "C:/Python34/so.py", line 11, in method
    print(self.foo)
AttributeError: 'Child2' object has no attribute 'foo' # second call fails

但是,由于不清楚代码到底应该做什么,我无法提出修复建议。例如,我不知道您为什么创建但没有在 MainWindow.initUI 中分配 ThndClass 实例。


这是一种可能的解决方法;将Child1 实例传递给Child2.__init__,然后将其用作Child2.method 的参数:

class Child2(Parent):

    def __init__(self, c1): # provide Child1 instance as parameter
        super().__init__()
        self.bar = "bar"
        self.method(c1) # pass instance to Child2.method

    def method(self, c1):
        c1.method() # call Child1.method with c1 as self parameter

(注意c1.method() 等价于Child1.method(c1)。)

或将其设为实例属性:

class Child2(Parent):

    def __init__(self, c1): # provide Child1 instance as parameter
        super().__init__()
        self.bar = "bar"
        self.c1 = c1 # make Child1 instance a Child2 instance attribute
        self.method() # now no argument needed

    def method(self):
        self.c1.method() # call Child1.method with c1 as self parameter

(注意self.c1.method() 等价于Child1.method(self.c1)。)

使用中(无论哪种方式):

>>> c1 = Child1()
>>> c2 = Child2(c1)
<class '__main__.Child1'> # Child1.method gets a Child1 instance
foo # and is called successfully

【讨论】:

  • 对不起,我真的不能让它更简单......我在评论中添加了第二部分,表明我的问题来自我从另一个类调用我的函数的事实,但那不t让它变得简单:(
  • 只想访问另一个类的函数:(就是这么简单:(
  • 访问该方法很好,但您不能将一个类作为self 传递,就好像它是另一个类并期望一切正常。
  • 好吧,如果我删除 self : TypeError: Getit() missing 1 required positional argument: 'self' 我会认为 Python 会很聪明地弄清楚当我调用 MainWindow.Getit 时(self) 我指的是我的 MainWindow 类的 self。那我该怎么办?
  • 你不能完全按照你的代码当前的结构来做——你无权访问ThndClass.initUI2中的MainWindow实例。您可以通过给它一个mw 参数显式地通过ThndClass.__init__ 传递一个,然后在MainWindow.initUI 中调用ThndClass(self),但是(再次)因为我不知道你想要实现什么我不知道这是否会让你有任何用处。
【解决方案2】:

感谢您的帮助 jonrsharpe,这是我的工作代码 :)

import sys
from PIL import Image
from PyQt4 import QtCore, QtGui




class MainWindow(QtGui.QWidget):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.initUI()

    def initUI(self):

        self.TestVar = 0
        self.TheCount = 2
        if self.TheCount ==2:
            self.TestVar = 2
            Themain = self
            ThndClass(Themain)







    def Getit(self):
        print("called correctly")
        print(self.TestVar)
        return  self.TestVar



def main():

    app = QtGui.QApplication([])
    mw = MainWindow()
    sys.exit(app.exec_())


class ThndClass(QtGui.QWidget):
    def __init__(self, Themain):
        super(ThndClass, self).__init__()
        self.Themain = Themain
        self.initUI2()

    def initUI2(self):
        print("Class Called")
        print(self.Themain.Getit())

if __name__ == '__main__':
    main()

现在一切正常 :) 非常感谢!

【讨论】:

  • 您可以简单地将Themain = self; ThndClass(Themain) 替换为ThndClass(self)。此外,这不应该是答案(或对问题的编辑);此处无需提供固定代码,接受我的回答即可。
  • 实际上,ThndClass(self) 对我来说并没有什么意义,因为我已经在二等舱中拥有了一个“自我”。事情变得混乱。在我写的路上,我明确地将 MainWindow self 传递给 TheMain ,然后将 TheMain 作为第二类的参数传递;所以一切都很简单明了。正如您所见,我已经添加了我的答案,因为我已经以稍微不同的方式解决了我的问题。我仍然不知道只有 ThndClass(self) 的代码应该是什么样子。但这肯定对我有帮助。
  • 您了解在一个函数或方法中分配给对象的名称与在另一个函数或方法中分配给它的名称完全无关,对?无论您在MainWindow.initUI(包括将其保留为self)中分配self(这里指的是MainWindow 实例)的任何名称,该对象仍将分配给ThndClass.__init__ 中的名称Themain,其中self(同样,即使您在MainWindow.initUI 中直接通过名称self 传递MainWindow 实例)将引用新的ThndClass 实例。
  • 有趣的链接谢谢,我明白你现在的意思是的,确实我只能写 ThndClass(self) ,class 1 的 self 将直接进入 class2 的第二个参数,我不需要给它同样的名字。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多