【问题标题】:difference between default and optional arguments默认参数和可选参数之间的区别
【发布时间】:2010-08-20 00:56:09
【问题描述】:

好的代码:

#!/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/ 提到了一种方法,其中默认和可选参数的数量不同! (有什么区别?)

UDPATE:

“它有七个参数。第一个参数没有默认值。其他六个参数有。这四个参数是可选的。前三个是强制性的。” - 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.

为什么没用?

【问题讨论】:

  • 当你说“它不运行”时,它是做什么的?错误?向我们展示详细信息。
  • 屏幕上没有出现窗口,但什么也没有出现
  • 您是否将文件命名为*.pyw?当我这样做时,我也对类语法错误“一无所获”(请参阅​​我的答案)。将它们命名为 *.py 和/或从控制台运行它们以进行开发,然后它实际上会向您显示错误。
  • 尼克,我得到一个“TypeError: Expected a 2-tuple of integers or a wxSize object.”。

标签: python wxpython optional-parameters keyword-argument


【解决方案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。后者会在看到错误时退出并将它们发送到 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>

关于关键字参数:

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 个参数,但您使用关键字告诉它去哪里。

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

【讨论】:

    【解决方案2】:

    您的Frame.__init__ 呼叫中缺少pos。这是来自docs 的原型:

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

    所以基本上错误是说它期望 size 是一个 2 元组或 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)
    

    【讨论】:

    • 我没有介绍过这个吗? :P 他没有删除大小,更多的是他删除了关键字参数并将它们替换为位置参数,这有效地做到了wx.Frame.__init__(self, parent, id=id, title=title, pos=size, size=style)
    • 啊,对 - 应该已经阅读了你的全部答案 - 我的印象是问题还没有解决。
    • 曾经是,然后不是,然后是,然后不是......这更像是讨论而不是问答:P
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    • 2013-10-08
    • 2015-02-23
    相关资源
    最近更新 更多