简体   繁体   English

为什么不能在 __init__ 中调用对象属性?

[英]Why can't you call object attributes within __init__?

I'm trying to understand why you can call an object's attribute within a class' method, but not within it's constructor.我试图理解为什么您可以在类的方法中调用对象的属性,但不能在其构造函数中调用。 For example:例如:

class Panel1(wx.Panel):

    #include Frame in the constructor
    def __init__(self, parent, frame):
        wx.Panel.__init__(self, parent)
        #set up so objects assigned in Frame (and it's children) can be called
        self.frame = frame
        button = wx.Button(self, label='Test')
        #button.Bind(wx.EVT_BUTTON, lambda event: self.onButton(event))
        button.Bind(wx.EVT_BUTTON, self.onButton)

        pprint(vars(self.frame))


    def onButton(self, event):
        print("Button pressed.")
        pprint(vars(self.frame))
        #the following fails in the constructor as panel2 for some reason is not callable
        a = self.frame.panel2.a
        print("123: " + str(a))

Could someone point me to a link that explains why this isn't possible in the constructor?有人可以给我一个链接来解释为什么在构造函数中这是不可能的吗?

Thanks!谢谢!

*****EDIT**** *****编辑****

Below is functional code to help explain my question better.以下是有助于更好地解释我的问题的功能代码。 If you try to call Panel2 attributes via the parent within Panel1's constructor, it fails.如果您尝试通过 Panel1 构造函数中的父级调用 Panel2 属性,则会失败。 But it works fine when done inside Panel1's onButton method.但是在 Panel1 的 onButton 方法中完成时它工作正常。 I'd like to understand why.我想了解为什么。

import wx
from pprint import pprint

class Panel1(wx.Panel):

    #include Frame in the constructor
    def __init__(self, parent, frame):
        wx.Panel.__init__(self, parent)

        self.frame = frame
        self.strPanel1 = "Panel1 string"
        self.intPanel1 = 0

        button = wx.Button(self, label='Test')
        button.Bind(wx.EVT_BUTTON, self.onButton)

        self.textbox = wx.TextCtrl(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)
        sizer.Add(self.textbox, 0, wx.ALL, 5)
        sizer.Add(button, 0, wx.ALL, 5)
        #pprint self.frame attributes fail here

    def onButton(self, event):
        #but not here!?!
        print("Panel1 button pressed.")
        pprint(vars(self.frame))
        Panel2str = self.frame.panel2.strPanel2
        print(Panel2str)
        Panel2int = self.frame.panel2.intPanel2
        print(str(Panel2int))
        #Panel2 button press counter
        self.frame.panel2.intPanel2 += 1
        self.frame.panel2.trigger()

    def trigger(self):
        print("Panel1 has been triggered")

class Panel2(wx.Panel):

    #include Frame in the constructor
    def __init__(self, parent, frame):
        wx.Panel.__init__(self, parent)

        self.frame = frame
        self.strPanel2 = "Panel2 string"
        self.intPanel2 = 0

        button = wx.Button(self, label='Test')
        button.Bind(wx.EVT_BUTTON, self.onButton)

        self.textbox = wx.TextCtrl(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)
        sizer.Add(self.textbox, 0, wx.ALL, 5)
        sizer.Add(button, 0, wx.ALL, 5)
        #pprint self.frame attributes fail here

    def onButton(self, event):
        #but not here!?!
        print("Panel2 button pressed.")
        pprint(vars(self.frame))
        Panel1str = self.frame.panel1.strPanel1
        print(Panel1str)
        Panel1int = self.frame.panel1.intPanel1
        print(str(Panel1int))
        #Panel1 button press counter
        self.frame.panel1.intPanel1 += 1
        self.frame.panel1.trigger()

    def trigger(self):
        print("Panel2 has been triggered")

class Frame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, title="My Frame")

        #Spliiting the frame
        splitter = wx.SplitterWindow(self)

        #Send frame to children
        self.panel1 = Panel1(splitter, self)
        self.panel2 = Panel2(splitter, self) 

        splitter.SplitVertically(self.panel1, self.panel2, 0)
        splitter.SetMinimumPaneSize(200)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(splitter, 1, wx.EXPAND)

        self.SetSizer(sizer)


if __name__ == '__main__':
    app = wx.App()
    frame = Frame()
    frame.Show()
    frame.Centre()
    app.MainLoop()

Below is functional code to help explain my question better.以下是有助于更好地解释我的问题的功能代码。 If you try to call Panel2 attributes via the parent within Panel1's constructor, it fails.如果您尝试通过 Panel1 构造函数中的父级调用 Panel2 属性,则会失败。

It fails, because at the time your Panel1.__init__ is called, frame.panel2 is not set yet.它失败了,因为在调用Panel1.__init__frame.panel2尚未设置。 Look at your Frame class:看看你的Frame类:

class Frame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, title="My Frame")

        #Spliiting the frame
        splitter = wx.SplitterWindow(self)

        #Send frame to children
        self.panel1 = Panel1(splitter, self)
        self.panel2 = Panel2(splitter, self)

        ...

When your Panel1 is initialized, panel2 is not set yet.当您的Panel1初始化时, panel2尚未设置。 It will only be set once Panel1 is done initializing and has been assigned to frame.panel1 .只有在Panel1完成初始化并已分配给frame.panel1才会设置它。 If you absolutely need to access panel2 into Panel1.__init__ , then you could make it so that your Panel1 take care of it.如果您绝对需要将panel2访问到Panel1.__init__ ,那么您可以进行设置,以便您的Panel1处理它。 For example:例如:

class Panel1:
    def __init__(self, frame):
        # Initialize panel2 and assign it to our frame
        frame.panel2 = Panel2(frame)

        # Now we can do whatever with panel2
        frame.panel2

class Panel2:
    def __init__(self, frame):
        pass

class Frame:
    def __init__(self):
        # This initialize panel1, and internally initialize panel2
        self.panel1 = Panel1(self)


frame = Frame()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果在 __init__ 定义中添加 *args,为什么不能省略 super 的参数? - Why can't you omit the arguments to super if you add *args in __init__ definition? 为什么您不必为在 python 中只有 __init__ 的 class 声明(对象)? - Why is it that you don't have to declare (object) for a class that only has __init__ in python? 为什么super(A,self).__ init __()不调用A的__init __()? - Why super(A, self).__init__() doesn't call A's __init__()? 为什么不能在子类的__init__中传递* args和** kwargs - Why can't pass *args and **kwargs in __init__ of a child class 为什么在__init__期间实例化的对象不能看到它们的创建者? - Why can't objects instantiated during __init__ see their creator? 为什么不能在__init__关键字arg中使用类变量? - Why can't class variables be used in __init__ keyword arg? 为什么 manage.py 看不到 __init__ 文件? - Why manage.py can't see the __init__ file? 在'__init__'中将对象的实例声明为'global' - Declaring an instance of an object as 'global' within '__init__' 为什么Python在实例创建时调用实例方法__init __()而不是调用类提供的__init __()? - Why doesn't Python call instance method __init__() on instance creation but calls class-provided __init__() instead? Python - 为什么在__init __()期间调用方法 - Python - Why call methods during __init__()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM