-1

アトミック型(int、string、...)は値によって渡され、他のすべて(オブジェクト、関数へのポインター、メソッドへのポインターなど)は参照によって渡されるようです。

変数が値または参照によって渡されるかどうかを確認するための最良の方法は何ですか?

isinstance(input_, float) or isinstance(input_, basestring) or <...>

とてもエレガントではないようです。

必要な理由は次のとおりです。wx.Buttonをラップするクラスがあります。args/kwargsが値によって渡される型である場合、他のオブジェクトでの値の更新は考慮されません。したがって、いくつかのチェックは有益です

class PalpyButton(wx.Button):        
    def __init__(self, parent, btnLabel, handler, successMsg = None, args = (), kwargs = {}):
        super(PalpyButton, self).__init__(parent, -1, btnLabel)
        self.handler = handler
        self.successMsg = successMsg
        parent.Bind(wx.EVT_BUTTON, lambda event: self.onClick(event, *args, **kwargs), self)
    def onClick(self, event, *args, **kwargs):
        try:
            self.handler(*args, **kwargs)
            if self.successMsg != None:
                if hasattr(self.successMsg, '__call__'):
                    showInfoMessageBox(self.successMsg())
                else:
                    showInfoMessageBox(self.successMsg)
        except BaseException, detail:
            showErrorMessageBox(detail)
4

2 に答える 2

11

という疑問は生じません。型、値、オペレーティング システム、月の満ち欠けなどに関係なく、すべてがまったく同じ方法で渡されます。

引数の受け渡しのスタイルが、値渡し、参照渡し、またはその他のいずれとして最もよく説明されるかどうかは、議論の余地があります (ただし、「値/参照による受け渡し」を使用するには、「値」/「参照」の非標準定義が必要であることに注意してください)これは、「オブジェクトによる受け渡し」などの他の用語の主な理由です)。ここは関係ありません。それはいつも同じです。

編集:handlerあなたの例に関しては、引数の型に基づいてのセマンティクスは変わりません。いずれかが変数に代入されます (AKA 名):

def my_handler(x):
    x = <whatever>

...しかしmy_handler(<anything>)、引数が参照するオブジェクトは変更されません(ローカル変数、オブジェクト属性、より複雑な式の結果、またはその他のものを渡すかどうかは問題ではありません)。ちなみに、すべてがオブジェクトであり、人為的な区別 (「アトミック」、「関数へのポインター」) は意味がありません。

あるいは、関数はオブジェクトの値を変更しようとします(例: コレクションへのアイテムの追加/削除、オブジェクト属性の変更、間接的に観察できる状態を変更するメソッドの呼び出し)。オブジェクトがそれをサポートしていない場合 (たとえば、存在しないメソッドを呼び出す場合) に例外が発生する可能性がありますが、これはミューテーションだけでなく、すべてのアクセスで発生します。オブジェクトの値が実際に変更された場合、これは常にすべてそのオブジェクトへの参照。既存のオブジェクトへの新しい参照は多くの場合 (引数の受け渡し、変数の割り当て、属性の割り当てなど) で作成されるため、ある場所で値を変更し、別の場所でその変更を観察することによって、オブジェクトがコピーされていないことを確認できます。 . これはすべてのオブジェクトに当てはまります (オブジェクトの値を変更できる場合)。

現在、一部のオブジェクトは不変です。これは、(定義により) それらの値を変更できないことを意味するため、この方法でオブジェクトの「共有」を観察することはできません (ただし、他の方法で観察することはできます)。これは、可変性に応じて代入のセマンティクスが異なるという意味ではなく (そうではありません)、不変オブジェクトではできないことを可変オブジェクトで実行できることを意味します。両方で実行できる操作は、両方で同じように機能します。

于 2012-11-28T11:41:34.173 に答える
-1

渡された変数の値を本当に変更する必要がある場合は、変数を配列でラップして、プロセスで参照渡しを実装できます。

def increaseInt(i_var):
  i_var[0] += 1

i_ref = [42]
increase(i_ref)
print i_ref[0]  # will print 43

場合によっては、これはあなたのような問題に対する (狡猾な) 解決策になる可能性があります。

しかし、一般に、Python ではすべての値が参照によって渡されます (コピーが作成されないという意味で)。一部の値は不変です (int、文字列、タプルなど)。パラメータ変数に新しい値を代入することで混乱するかもしれません — 以前のパラメータ変数にあった値は絶対に変更されず、新しい値で上書きされるだけです (したがって、元の値への追加の参照が削除されます)。i_varそのため、上記の例では に何かを代入していますが、 には何も代入していませんi_var[0]

于 2012-11-28T12:25:51.527 に答える