2017-05-29 4 views
3

私が書いているプログラムは、バイナリ演算を適用して整数を操作します(例えば>>,、|)。操作の多くは、関数の内部で適用され、操作の結果は、私が変更された変数のコピーを返すよ、一度関数リターンを持続させるために。Pythonでの整数のビット単位の変更

ような何か:

updated = applyOp(original, amnt) 

def applyOp(original, amnt): 
    return original >> amnt 

私は整数のコピーを返すようにしたいし、代わりに、関数の外を永続化する関数内originalに加えられた変更を望んでいなかった場合、私は私が作成することができたとしに何らかのラッパークラス。他のオプションはありますか?おそらくビット賢明な整数操作を容易にするものでしょうか? Pythonで

答えて

2

は、変数への代入は、特定のメモリ位置の値ではなく、バインディング変数を変化させます。あなたが記述している方法で変更を可能にするためには、可変バインディングではなく、保存されたデータを変更する必要があると思います。以下の例を見てみましょう:割り当てがバインディング変数を変更

a = 1 
b = a 
a = 2 

ので、aは今2にバインドされていますが、bはまだ1にバインドされています。あなたは本当に逆の振る舞いが必要ですが、私の知る限り、この振る舞いはPythonでは利用できません。

正しく言うように、これは、ラッパーのいくつかの並べ替えが必要になります。しかし、この目的のためのクラスは厳密には必要ではありません。これを達成する最も簡単な方法の1つは、データをリストに入れることです。 (何も再割り当てがどちらかに行われなかったので)

a = [1] 
b = a 
a[0] = 2 

さて、abはまだ同じリストが含まれており、そのa[0] == b[0] == 2:この例を見てみましょう。したがって、有効な解決策の1つは、値を直接渡すのではなく、関数に単一項目リストを渡すことです。

別の答えは、同じクラスの両方のメソッドにすることで、関数間でデータを共有することができますが、もちろんメンバー変数を共有できます。しかし、このアプローチがあなたにとって適切なものであれば、私はあなたの限られた情報からはわかりません。ここで

が、これは潜在的に仕事ができる方法の例です:

再び
class MyClass: 
    def __init__(self): 
     self._value = 0; 

    def do_something(self): 
     # Do something with self._value 
     self._helper_function() 
     # Continue using self._value 

    def _helper_function(self): 
     # No need to pass the value in. It is accessible at self._value 

、これがうまくいくかどうか、あなたがやろうとしている正確に何に依存します。

+0

私は "同じクラスのアプローチ"に興味があります。私はそれが問題を解決する方法を確認しようとしています - 整数メンバ変数を持つクラスを作成し、その変数をクラス関数に渡した場合でも、メンバ変数への参照のコピーを作成しています。それは私がそれを再割り当てすることができないことを意味します(私が現在直面している同じ問題)。 – Adam

+1

@Adamこれがどのように機能するかの例を追加するために編集しました。 – bytesized

0

私はあなたがCのような言語から来ていると、まだパイソンの内部を自分で慣れていないことを推測しています。 Pythonで

は、すべてのオブジェクトが参照によって渡されます。これは、関数を呼び出すときにコピーが行われていないことを意味します。あなたは、オブジェクトのID(メモリ位置)を見て、これをテストすることができます

x = 0 

print(id(x)) 

def f(y): 
    print(id(y)) 

f(x) 

どちらの場合も、IDは同じであるので、彼らは実際には同じオブジェクトではなくコピーされています。どのように価値の仕事を変えてしまうためまず

これは、ばかげているようですか?

x = 1 
print(id(x)) 
x += 2 
print(id(x)) 

ご覧のとおり、IDが変更されました。 xが増加するのではなく、全く新しいオブジェクトが得られました!これは、int不変型であるためです。

つまり、オブジェクトに対して操作が実行されると、オブジェクト自体を変更する代わりに新しいオブジェクトが返されます。反対のものは、変更可能な変更可能な型です。

パイソンstrfloatinttupleタイプdictlistset種類は可変であるが、不変です。

しかし、一般的には、このようなことについて心配することなく、実装の詳細とわずかなパフォーマンスの違いについて気にする必要はありません。コードがうまく動作するようにして、最初に読み込み可能にし、実際に発生した可能性のあるパフォーマンスの問題を処理します。