5

最近私はこのようなことをしています:

import Tkinter
class C(object):
    def __init__(self):
        self.root = Tkinter.Tk()
        def f():
            print 'hello'
        self.button = Tkinter.Button(master=self.root, command=f, text='say hello')

このようなものとは対照的に:

import Tkinter
class C(object):
    def __init__(self):
        self.root = Tkinter.Tk()
        self.button = Tkinter.Button(master=self.root, command=self.f, text='say hello')
    def f(self):
        print 'hello'

質問はTkinterに固有のものではありませんが、良い例です。この関数fはボタンのコールバックとしてのみ使用されるため、内部で定義することを選択しました__init__。そうすれば、内部のコードだけがの存在__init__を知ることがfできます。外部スコープが名前で乱雑になり始めることはなく、ユーザーは内部用に設計されたメソッドの負荷を気にする必要がありません。

私の質問は:これは良いスタイルと見なされますか?非常に多くのボタンを備えたGUIクラスがあるため、心配してい__init__ます。ローカル関数の定義が多く、非常に長く見え始めています。私が使用すべきより適切な代替手段はありますか?

4

2 に答える 2

8

のコンテキストでこのようなことを行う一般的な方法は、関数Tkinterを使用するlambdaことです。

self.button = Tkinter.Button(master=self.root, 
                             command=lambda:sys.stdout.write("Hello!\n"),
                             text='say hello')

基本的に、これは最初の例と実際には同じです。したがって、最初の方法を好む場合は、それを使用してください。この場合、新しいメソッドを作成することは一般的に慣用的ではないと思います(実際にインスタンスをコールバックに渡す必要がある場合を除きます。その場合は、2番目の方法で行う必要があります)。

ここで心配することが2つあります。1つ目は読みやすさです。散らかって読めない場合__init__は、問題があります。これらの関数をモジュールレベルに移動し(コンテキスト_にインポートされないように接頭辞として) 、必要に応じてローカル変数を引数としてこれらの関数にバインドするために使用できます。from module import *lambda

__init__散らかっていない場合は、関数を自由に配置してください。そこに関数があるということは、新しいインスタンスが作成されるたびに(と同じ)新しい関数が作成されることを意味します。lambdaこれは、メモリに関する限り無駄になる可能性がありますが、それほど大きな問題ではないはずです(特にGUIで)。

次に心配するのは、名前空間の乱雑さです。ただし、モジュールが大きすぎてこれらのローカル関数をモジュールレベルの関数に移動すると名前空間の問題が発生する場合は、モジュールが大きすぎて最初から使用できません。関数の前にアンダースコアを付ける限り(上記の提案を参照)、このモジュールを他のモジュールにインポートする際に名前空間の問題が発生することはありません。

于 2012-09-04T15:54:25.777 に答える
2

この場合、それは無害です。ただし、全体として、次の2つの理由で回避します。

1)クラスのメンバーとしてのコールバックの定義は、いくらか読みやすくなっています(特に、pydocを使用して調査している場合)。

2)別の関数内に関数を作成すると、より多くのクロージャ(呼び出し元のコンテキストから継承された変数)が導入されます。

于 2012-09-04T15:59:10.140 に答える