[英]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.