Python 单击带有提示且默认隐藏的选项

Python click option with a prompt AND default hidden

下面的代码片段提示输入用户和密码,默认为环境变量。

现在,虽然输入的密码在输入时被很好地隐藏了,但我也想隐藏方括号之间的默认值,到目前为止,如果我输入这个,默认密码是明文 1234 :

➜  export PASSWORD=1234
➜  python test.py
➜  User [myuser]: you can see here
➜  Password [1234]: 
user you can see here
password you cant see


import os
import click

@click.command()
@click.option('--user', prompt=True, default=lambda: os.environ.get('USER', ''))
@click.option('--password', prompt=True, default=lambda: os.environ.get('PASSWORD', ''), hide_input=True)
def test(user, password):
    print('user {}'.format(user))
    print('password {}'.format(password))
    print(password)


if __name__ == '__main__':
    test()

找不到更好的解决方案,但也许可以。您可以使用 callback for validation 检查输入值,如果未提供输入,则将其替换为环境值。

def callback(ctx, param, value):
  if not value:
    return os.environ.get('PASSWORD', '')
  return value
...
@click.option('--password', prompt=True, callback=callback, default='', hide_input=True)

您可以制作一个 class 其字符串表示隐藏密码:

class HiddenPassword(object):
    def __init__(self, password=''):
        self.password = password
    def __str__(self):
        return '*' * len(self.password)

然后在您的代码中,您只需检查是否使用了此 class 并更新密码:

@click.command()
@click.option('--user',
              prompt=True,
              default=lambda: os.environ.get('USER', ''))
@click.option('--password',
              prompt=True,
              default=lambda: HiddenPassword(os.environ.get('PASSWORD', '')),
              hide_input=True)
def test(user, password):
    print('user: {}'.format(user))
    if isinstance(password, HiddenPassword):
        password = password.password
    print('password: {}'.format(password))

进行中:

$ PASSWORD=foobar python test.py
User [mVChr]:
Password [******]:
user: mVChr
password: foobar
$ PASSWORD=foobar python test.py
User [mVChr]: dan
Password [******]:
user: dan
password: user-entered-pw