2010-12-14 5 views
1

Currectly、私は以下しようとしている:一部のmutator機能がlocals()別のスコープの変数を変更するには?

def mutator(locals): 
    locals['n'] = 10 
    locals['l'].append(10) 

def f(): 
    n = 1 
    l = [1] 
    mutator(locals()) 
    print(n,l) # >>> 1, [1,10] 

f(None) 

を使用して他の関数のローカルスコープを受け入れ、それが期待どおりに動作:私は変更可能なリストの内容を変更することができましたが、別の不変「を再バインド」することができませんでしたintを同じ名前にします。

現在、私はいくつかのオプションを参照してください。

  • eval()を、exec() &共同
  • スタックフレームとプレイmutator()
  • で&ローカル変数はdictで、このような変数を保持:非常に便利ではないが、おそらく、最良のもの

制限は:target fu f()には引数付きの関数呼び出しを1つだけ含めることができ、その関数はf()の現在のスコープ内の値を変更できる必要があります。

だから、実行時に変数の値(別のオブジェクトをバインドする)を再導入する方法はありますか?私はこれを達成する良いトリックがないとは思わない!ここで


は私が達成しようとしているものの例です:

def view(request): # Yes, that's Django! 
    q = MyModel.objects.all() 

    data = { 'some_action': True, 'items_per_page': 50 } # defaults. Mutators can change this 
    mutators.launch(locals(), data) # Launch mutators that may want to narrow the QuerySet 

    if data['some_action']: # do something useful if no mutator has disabled it 
      ... 

    # paginate using data['items_per_page'] 

私はここにdata辞書を使用したくない:ローカル変数としてそれらを修正する機能が&ずっと良いだろうかなり。 q QuerySetオブジェクトは変更可能です&ミューテータはその内容を変更できます。

+0

は、より多くの書式設定が必要です。メソッド本体をインデントします。 – Robert

+6

あなたは正確に何を達成しようとしていますか? – Falmarri

+0

これは、関数の内部ロジックの実行時の外部チューニングの方法になるでしょう:)特定のブール値をオン/オフに切り替えて機能を有効/無効にしたり、一部のリストをサブセットに絞り込んだりするなど、高度にカスタマイズ可能なシステムのための良いチューニングと拡張フレームワークを実装する最良の方法です。 – kolypto

答えて

3
class AttributeCollection(object): 
    pass 
shared_settings= AttributeCollection() 
# now improvise 
shared_settings.temperature= 30 
shared_settings.samples= [] 
# etc 

パス周辺shared_settings、またはそれはグローバルに、そしてあなたが望むものは何でもその属性を設定しています。

関数のlocals()は、その関数内で(そしてその関数が実行されている間に)操作されることを意味する(そしてそのために最適化された)名前空間に過ぎません。あなたのコードの共通の遊び場として別の名前空間(私の提案では、shared_settingsオブジェクト)を使用してください。

+2

+1はクラス内のすべてをカプセル化します。ブロブ内のローカル変数を他の人に送信することを考えると、私は悩まされます。 – spade78

+0

ただ一つのこと: 'dict'を使うのではなく、クラスをインスタンス化する理由はありますか?とにかく '__dict__'属性を使用します。 – kolypto

+1

@o_O:クラスをインスタンス化すると、属性アクセスにドット表記を使用できます。あなたがgetitem表記法を使うつもりなら、是非:dictを使ってください。 – tzot

0

は、このようにそれを実行します。

def mutator(l): 
    l.append(10) 
    return 10 

def f(): 
    n = 1 
    l = [1] 
    n = mutator(l) 
    print(n,l) # >>> 1, [1,10] 

f() 

ええ、私はそれはあなたが望む巧妙なハックではありません知っています。それは動作します。 :-)

あなたがオンにすることができ、グローバルコンフィギュレーションオプションのセットやチューニングをしたい場合は、オブジェクトにそれらのすべてをスティック:

class Settings(object): 
    def __init__(self): 
     self.n = 1 
     self.l = [1] 

今、あなたはあなたの心のコンテンツへの変数を変更することができます。

+0

:)))nice!しかし、私は複数の値を返す必要がある場合、それはうまく見えません。 IMHO単一のdictを使う方が良いです: 'self.n'はとにかく' self .__ dict__'を使用します – kolypto

+1

...そしてなぜあなたは複数の値を返す必要がありますか?彼らはすべて設定で一緒に縛られている! :) –