3

私は自分が次のコードを書いていることに気づきました。

def dlt(translation):
    del translation.strands[translation.active][translation.locus]

私はむしろ次のようなものを好みます:

def dlt(translation):
    *something*(translation):
        del strands[active][locus]

これを達成する方法はありますか?

4

2 に答える 2

4

名前空間は単なるPythonオブジェクトであり、オブジェクト(属性ルックアップの結果を含む)をローカル変数名に割り当てることができます。

strands = translation.strands
active = translation.active
locus = translation.locus

または、この回答locals()に示すように、変更するコンテキストマネージャーを一緒にハックする必要があります。

このような何かはそれをするでしょう:

import inspect

class Namespace(object):
    def __init__(self, namespaced):
        self.namespaced = namespaced

    def __enter__(self):
        """store the pre-contextmanager scope"""
        ns = globals()
        namespaced = self.namespaced.__dict__
        # keep track of what we add and what we replace
        self.scope_added = namespaced.keys()
        self.scope_before = {k: v for k, v in ns.items() if k in self.scope_added}
        globals().update(namespaced)
        return self

    def __exit__(self):
        ns = globals()
        # remove what we added, then reinstate what we replaced
        for name in self.scope_added:
            if name in ns:
                del ns[name]
        ns.update(self.scope_before)

次に、次のように使用します。

with Namespace(translation):
     del strands[active][locus]

内のすべてのアイテムは、ブロックtranslation.__dict__内でグローバルに利用可能になります。while

これはスレッドセーフではないことに注意してください。将来、自分自身を含め、これを使用するコードを読み込もうとする人にとっては、多くの混乱を招く可能性があります。個人的にはこれは使いません。

于 2012-11-09T17:17:29.557 に答える
2

あなたはおそらくMartijnの答えを使うべきです。しかし、あなたが本当にあなたが求めたことをやりたいのなら、私はこの(テストされていない)スニペットがそれをするだろうと思います:

exec "del strands...", translation.__dict__

それが気に入らない場合:良い、あなたは味があります。:-)

別のオプションは次のとおりです。

def within(obj, func):
    return func(**obj.__dict__)

このように呼んでください:

def dostuff(strands, active, locus, **ignored):
    del ...
within(translation, dostuff)
于 2012-11-09T17:31:21.630 に答える