Python argparse parse_args в глобальное пространство имен (или причина, по которой это плохая идея)
Я в основном использовал argparse для создания сценариев командной строки в python, и обычно я использую идиому, что я назначаю аргументы как атрибуты объекта, а затем анализирую их по отдельности для переменной, которая соответствует имени их атрибута. Это кажется немного повторяющимся. Есть ли способ назначить их всех в глобальное пространство имен и вырезать шаг назначения; или как часто бывает, когда какое-то поведение python кажется мне нелогичным, может ли какой-нибудь мудрый эксперт по python указать, что есть веская причина, по которой я не должен этого делать или хочу делать это?
Что у меня сейчас есть, это:
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--db",type=str, dest='db', nargs='?', default="test")
parser.add_argument("--collection",type=str, dest='collection', nargs='?', help="Collection, default is test", default="test")
args = parser.parse_args()
db = args.db # gross!
collection = args.collection # yuck!
print(db)
print(collection)
Что я хотел бы это:
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--db",type=str, dest='db', nargs='?', default="test")
parser.add_argument("--collection",type=str, dest='collection', nargs='?', help="Collection, default is test", default="test")
parser.SUPER_parse_args() # now, db and collection are already in the namespace!
print(db)
print(collection)
Это не так уж и много, когда у меня только 2 аргумента, но если у меня их 10 или около того, удвоение шагов присваивания, когда я переименовываю в глобальное пространство имен атрибуты, которые уже существуют в объекте args, начинает меня беспокоить.
3 ответа
Вы можете сделать это используя globals
:
globals().update(args.__dict__)
однако, вы действительно *не должны этого делать. Из дзен питона,
Пространства имен - одна из отличных идей - давайте сделаем больше!
Я повторю то, что @Martijn сказал в своем комментарии:
Не. Просто не надо. Я бы использовал
args
прямо вместо.
Держите вещи как можно лучше отделенными друг от друга. Это делает код более понятным и легким для понимания.
Это то, что я сделал. Это помогает с переменным столкновением, но не ремонтопригодностью.
parser_args = parser.parse_args()
if parser_args.verbose:
globals().update(argparse.Namespace(verbose=parser_args.verbose).__dict__)
Добавить к ответу Мильсона:
Рассмотреть возможность использования locals().update(args.__dict__)
вместо; это обновит текущее пространство имен, а не глобальное пространство имен.
Вы также можете сделать это, используя locals() или vars(). См. Этот пост переполнения стека для хорошего объяснения разницы между ними.
Я немного опаздываю на Mittonchops, но, надеюсь, это поможет другим.