默认参数和可选参数的区别

2 投票
2 回答
2159 浏览
提问于 2025-04-16 03:03

好的代码:

#!/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()

添加的内容:

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)

替换的内容:

frame = wx.Frame(None, -1, title='Redirect Test', size=(620,450), style=wx.STAY_ON_TOP|wx.DEFAULT_FRAME_STYLE)

用这个:

frame = MyFrame(None, -1, title='Redirect Test', size=(620,450), style=wx.STAY_ON_TOP|wx.DEFAULT_FRAME_STYLE)

现在,它不运行了……

我想在我的代码中多次调用 MyFrame 的构造函数,并传入不同的参数。

我尝试了很多方法……

用所有参数实例化 MyFrame
用所有参数和默认参数实例化 myFrame
构造函数的方法签名包含所有参数
构造函数的方法签名包含所有参数,但有默认参数
用所有参数调用父类的构造函数
用所有参数和默认参数调用父类的构造函数

而且教程 http://zetcode.com/wxpython/ 提到了一种方法,其中默认参数和可选参数的数量是不同的!(这有什么区别?)

更新:

“它有七个参数。第一个参数没有默认值。其他六个参数都有。那四个参数是可选的。前三个是必须的。” - http://zetcode.com/wxpython/firststeps/

更新 2:

经过分号的修正,我刚刚尝试了:

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title, size, style):
        wx.Frame.__init__(self, parent, id, title, size, style)
  • 我说明了要传入哪些参数(第二行)
  • 我用传入的参数进行调用(第三行)

更新 3:

完整的错误信息是:

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.

为什么它不工作?

2 个回答

1

你在调用 Frame.__init__ 时缺少了 pos 参数。这里是文档中的原型:

Frame.__init__(self, parent, id, title, pos, size, style, name)

所以基本上这个错误是在说,它期望 size 是一个包含两个值的元组或者是 wxSize 对象,而你传入的东西不符合这个要求。我猜这个问题是在你从构造函数中去掉了 size= 之后出现的:

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title, size, style):
        wx.Frame.__init__(self, parent, id, title, size, style)

补充:下面的任意一种写法都是可以的

        wx.Frame.__init__(self, parent, id, title, size=size, style=style)
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, size, style)

但是因为你在参数中省略了关键词,所以你的调用是按照传入的顺序来处理的,如下:

        wx.Frame.__init__(self, parent, id, title, pos=size, size=style)
1

对我来说运行得很好,只需要一个小改动;你在子类化的 wx.Frame 语句后面缺少一个冒号。

有一点建议;如果你只是想把参数“传递”给父类的初始化器,可以使用 *args 和/或 **kwargs,这样可以少打一些字。

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

如果你想修改或添加特定的参数,可以直接修改字典 kwargs,比如:

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        kwargs['size']=(1000,200)
        wx.Frame.__init__(self, *args, **kwargs)

关于开发时运行文件:

在控制台中用 python 运行你正在工作的脚本,而不是用 pythonw。后者在遇到错误时会直接退出,并把错误信息丢到一边。

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>

关于关键字参数:

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)

当你以关键字的方式传递参数,比如标题、大小、样式时,它们在实际接收这些参数的函数中的位置可能完全不同。这里的第一行把“大小”赋值给 wx.Frame.__init__ 函数的第五个参数,但这可能并不是“大小”。它可能是第100个参数,但你用关键字来告诉它该放在哪里。

“可选”这个词有点模糊;关键字参数提供默认值,但这个默认值可能并不合适。

撰写回答