あとで情報の取得ができるような感じに

途中。何かできそうな感じだけど。綺麗じゃない。

やりたいことは、デコレータで指定しておくと、指定したKeyが無かったときには自動でそれを取得するようなもの。
(呼び出す関数は必ず第一引数がdict like object)

import getpass
import urllib

class HiddenInputIter(object):
    def __init__(self, fields):
        self.fields = fields

    def tell_iter(self):
        for field in self.fields:
            yield field, lambda : getpass.getpass(field+": ")

    def tells(self):
        return [e for e in self.tell_iter()]

class WithAccount(object):
    """decorator: a target function is recive account(dict like object) as 1st argument.
    when decorated function called, iff account hasn't receved key, get value with hiddeninput and set.
    """
    def __init__(self, *fields):
        self.fields = fields
        self.hi = HiddenInputIter(fields)

    def with_account(self, fn):
        def _with_account(account, *args, **kw):
            assert getattr(account, "get")
            val, status = fn(account, *args, **kw)
            if status is None:
                for k, inpfn in self.hi.tell_iter():
                    if not k in account:
                        account[k] = inpfn()
                return fn(account, *args, **kw)
            else:
                return val
        return _with_account

    def with_input(self, fn):
        def _with_input(account, *args, **kw):
            for k in self.fields:
                if not k in account:
                    return None, None
                
            v = fn(account, *args, **kw)
            return v, True
        
        return self.with_account(_with_input)

    __call__ = with_input

class Shell(dict):
    @WithAccount("user")
    def repl(self):
        print "%s >" % self["user"], 
        return raw_input()

sh = Shell()
while True:
    sh.repl()

実行

$ python foo.py
user: 
foo > bar
foo > bar
foo > zoo
foo > Trace