difference between default and optional arguments
okay code:
#!/usr/bin/python
import wx
import sys
class XPinst(wx.App):
def __init__(self, redirect=False, filename=None):
wx.App.__init__(self, redirect, filename)
def OnInit(self):
frame = wx.Frame(None, -1, title='Redirect Test', size=(620,450), style=wx.STAY_ON_TOP|wx.DEFAULT_FRAME_STYLE)
panel = wx.Panel(frame, -1)
log = wx.TextCtrl(panel, -1, size=(500,400), style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
redir=RedirectText(log)
sys.stdout=redir
print 'test'
frame.Show()
return True
class RedirectText:
def __init__(self,aWxTextCtrl):
self.out=aWxTextCtrl
def write(self,string):
self.out.WriteText(string)
app = XPinst()
app.MainLoop()
added:
class MyFrame(wx.Frame)
def __init__(self, parent, id, title, size=(620,450), style=wx.STAY_ON_TOP|wx.DEFAULT_FRAME_STYLE):
wx.Frame.__init__(self, parent, id, title, size=(620,450), style=wx.STAY_ON_TOP|wx.DEFAULT_FRAME_STYLE)
replaced:
frame = wx.Frame(None, -1, title='Redirect Test', size=(620,450), style=wx.STAY_ON_TOP|wx.DEFAULT_FRAME_STYLE)
with:
frame = MyFrame(None, -1, title='Redirect Test', size=(620,450), style=wx.STAY_ON_TOP|wx.DEFAULT_FRAME_STYLE)
Now, it doesn't run...
I want to be able to call the MyFrame constructor more than once in my code passing different arguments
I tried many things...
instanciating MyFrame with all arguments instanciating myFrame and with all, but default arguments
constructor method signature with all arguments constructor method signature with all, but default arguments calling parent constructor method with all arguments calling parent constructor method with all, but default argumentsplus the tutorial http://zetcode.com/wxpython/ mentions a method where the number of default and optional arguments are different! (what's the difference?)
UDPATE:
"it has seven parameters. The first parameter does not have a default value. The other six parameters do have. Those four parameters are optional. The first three are mandatory." - http://zetcode.com/wxpython/firststeps/
UPDATE 2:
With semi-开发者_运维技巧colon correction, i have just tried:
class MyFrame(wx.Frame):
def __init__(self, parent, id, title, size, style):
wx.Frame.__init__(self, parent, id, title, size, style)
- I tell what arguments are going in (second line)
- I call with the arguments that went in (third line)
UPDATE 3:
the full error message is:
Traceback (most recent call last):
File "test.py", line 29, in <module>
app = XPinst()
File "test.py", line 8, in __init__
wx.App.__init__(self, redirect, filename)
File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 7978, in __init__
self._BootstrapApp()
File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 7552, in _BootstrapApp
return _core_.PyApp__BootstrapApp(*args, **kwargs)
File "test.py", line 10, in OnInit
frame = MyFrame(None, -1, title='Redirect Test', size=(620,450), style=wx.STAY_ON_TOP|wx.DEFAULT_FRAME_STYLE)
File "test.py", line 21, in __init__
wx.Frame.__init__(self, parent, id, title, size, style)
File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_windows.py", line 497, in __init__
_windows_.Frame_swiginit(self,_windows_.new_Frame(*args, **kwargs))
TypeError: Expected a 2-tuple of integers or a wxSize object.
Why didn't it work?
Runs fine for me with one tweak; you're missing a colon after your subclassed wx.Frame
statement.
One comment; if you're just "passing through" arguments to the parent initalizer, use *args
and/or **kwargs
to save some typing.
class MyFrame(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
If you want to modify or add particular arguments, you could just modify the dictionary kwargs
, e.g.
class MyFrame(wx.Frame):
def __init__(self, *args, **kwargs):
kwargs['size']=(1000,200)
wx.Frame.__init__(self, *args, **kwargs)
On running files for development:
Run scripts you're working on in the console, with python
, not pythonw
. The latter will just quit when it sees errors and send them off to lala-land.
N:\Code>pythonw wxso.pyw
N:\Code>rem nothing happened.
N:\Code>python wxso.pyw
File "wxso.pyw", line 24
class MyFrame(wx.Frame)
^
SyntaxError: invalid syntax
N:\Code>
On keyword arguments:
class MyFrame(wx.Frame):
def __init__(self, parent, id, title, size, style):
#wx.Frame.__init__(self, parent, id, title, size, style) # broken
# equivalent to:
#wx.Frame.__init__(self, parent, id=id, title=title, pos=size, size=style)
# the below works.
wx.Frame.__init__(self, parent, id, title=title, size=size, style=style)
When you pass arguments as keywords e.g. title, size, style, their position to the function that actually takes them could be totally different. The first line there assigns "size" to whatever is the fifth argument in the wx.Frame.__init__
function, which is probably not size. It could be the 100th argument, but you use the keyword to tell it where to go.
"Optional" is somewhat vague; keyword arguments supply defaults, but the default may be inappropriate.
You're missing the pos
from your Frame.__init__
call. Here's the prototype from the docs:
Frame.__init__(self, parent, id, title, pos, size, style, name)
So basically the error is saying that it expects size
to be a 2-tuple or wxSize object, and what you were passing doesn't match that. I'm guessing that this crept in when you removed size=
from the constructor here:
class MyFrame(wx.Frame):
def __init__(self, parent, id, title, size, style):
wx.Frame.__init__(self, parent, id, title, size, style)
Edit: Either of the following would be fine
wx.Frame.__init__(self, parent, id, title, size=size, style=style)
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, size, style)
but by omitting the keywords from the arguments, your call was being handled in the order passed, as
wx.Frame.__init__(self, parent, id, title, pos=size, size=style)
精彩评论