Python argparse parse_known_args(namespace=); использование пространства имен?

Пытаясь понять pymol-open-source setup.py, я наткнулся на такое использование argparse.parse_know_args()namespace ключевое слово:

import argparse
...

class options:
    osx_frameworks = True
    jobs = int(os.getenv('JOBS', 0))
    no_libxml = False
    no_glut = True
    use_msgpackc = 'guess'
    testing = False
    openvr = False
    use_openmp = 'no' if MAC else 'yes'
    use_vtkm = 'no'
    vmd_plugins = True
...

parser = argparse.ArgumentParser()
parser.add_argument('--glut', dest='no_glut', action = "store_false",
                    help = "link with GLUT (legacy GUI)")
parser.add_argument('--no-osx-frameworks', dest='osx_frameworks',
                    help = "on MacOS use XQuartz instead of native frameworks",
                    action = "store_false")
parser.add_argument('--jobs', '-j', type=int, help = "for parallel builds "
                    "(defaults to number of processors)")
parser.add_argument('--no-libxml', action = "store_true",
                    help = "skip libxml2 dependency, disables COLLADA export")
parser.add_argument('--use-openmp', choices=('yes', 'no'),
                    help = "Use OpenMP")
parser.add_argument('--use-vtkm', choices=('1.5', '1.6', '1.7', 'no'),
                    help = "Use VTK-m for isosurface generation")
parser.add_argument('--use-msgpackc', choices=('c++11', 'c', 'guess', 'no'),
                    help = "c++11: use msgpack-c header-only library; c: link against "
                    "shared library; no: disable fast MMTF load support")
parser.add_argument('--testing', action = "store_true",
                    help = "Build C-level tests")
parser.add_argument('--openvr', dest='openvr', action='store_true')
parser.add_argument('--no-vmd-plugins', dest='vmd_plugins',
                    action='store_false',
                    help='Disable VMD molfile plugins (libnetcdf dependency)')
options, sys.argv[1:] = parser.parse_known_args(namespace=options)
...

где в options, sys.argv[1:] = parser.parse_known_args(namespace=options), namespace указывает на класс options.

Я думаю, он используется для фильтрации sysy.argv для передачи setuptools.setup?

Это предпочтительный/питоновский/правильный способ использования parser.parse_known_argsnamespace?

Обычно тип пространства имен возвращает <class 'argparse.Namespace'> при использовании этого.

Я получил <class '__main__.Namespace'>.

Задокументировано ли такое поведение для argparse, принимают ли ключевые слова namespace другие типы объектов, которые могут быть полезны для навигации по параметрам предварительной настройки?

Пожалуйста, потерпите меня, я не эксперт в Python, setptools и argparse.

что непонятно. Я спрашивал, правильно ли передавать объект класса в качестве ключевого слова пространства имен в argparser.pares_know_args? Или, если в Python правильно хранить значения как атрибуты класса, я считаю, что если не ошибаюсь, это не считается хорошим программированием на Python. -И мне было интересно, почему пространство имен принимает это и может ли оно принимать другие объекты, такие как словарь и т. д.

pippo1980 17.07.2024 15:38

ошибки в коде конечно нет

pippo1980 17.07.2024 15:40

Я вижу три отдельных вопроса, один из которых кажется расплывчатым (что именно представляет собой «эта задача»?), а два из них кажутся второстепенными («задокументировано ли это» и «есть ли еще?», что простирается на слишком широкие рамки). территория). Пожалуйста, сосредоточьтесь на одном, четко определенном вопросе. Возможно, объясните более подробно, что происходит и с каким аспектом вам нужна помощь.

tripleee 17.07.2024 16:02

Это предпочтительный/питоновский/правильный способ использования пространства имен parser.parse_known_args?

pippo1980 17.07.2024 16:05

Вы можете использовать свой собственный класс вместо класса по умолчанию Namespace, если у вас есть для этого основания. Я удивлен, что вы видите <class '__main__.Namespace'> в своем коде, я ожидал __main__.options. Вы уверены, что это репрезентативный результат? Возможно, это ваш вопрос? Кроме того, стоит ли вам использовать свой собственный класс? Если у вас нет причины, нет. Если да, то да.

deceze 17.07.2024 16:09

.... Обычно тип пространства имен возвращает <class 'argparse.Namespace'> при использовании этого... Я не имел в виду этот пример. Если я использую параметры, sys.argv[1:] = parser.parse_known_args(namespace=options) ; тип (опции) — пространство имен. Немного выше.... где в опциях sys.argv[1:] = parser.parse_known_args(namespace=options), пространство имен указывает на класс опций. ---> __main__.options

pippo1980 17.07.2024 16:13

По сути, это использование экземпляра type вместо экземпляра argparse.Namespace для хранения определенных аргументов. Это немного неортодоксально, поскольку определяет класс без намерения создать его экземпляр.

chepner 17.07.2024 16:25

Возможно, более ортодоксальным подходом было бы использовать метод set_defaults для предоставления значений по умолчанию для различных аргументов, а не инициализировать options или экземпляр Namespace вручную.

chepner 17.07.2024 16:44
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
9
82
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Да, обычно можно просто использовать поведение по умолчанию parse_known_args, создавая экземпляр argparse.Namespace для хранения результатов и используя метод set_defaults для предоставления значений по умолчанию. Что-то вроде

import argparse

[...]



parser = argparse.ArgumentParser()
[...]
parser.set_defaults(osx_frameworks=True,
                    jobs=int(os.getenv('JOBS', 0)),
                    no_libxml=False,
                    # etc)

options, sys.argv[1:] = parser.parse_known_args()

Автор этой библиотеки решил вместо этого использовать класс (экземпляр type) вместо экземпляра Namespace для хранения аргументов и инициализации атрибутов класса их значениями по умолчанию.

(Кроме того, можно указать значения по умолчанию для каждого аргумента в соответствующем вызове add_argument. set_defaults полезен для инициализации целей, которые могут быть установлены несколькими аргументами или которые создаются только условно после анализа.)

просто чтобы убедиться, что я все правильно понимаю, аргументы по умолчанию обрабатываются как известные аргументы с помощью parser.parse_known_args() ?

pippo1980 17.07.2024 17:21

Значения по умолчанию для цели используются, если цель не задана иным образом вызовом parse_known_args.

chepner 17.07.2024 17:23

Здесь просто чтобы попытаться добавить соответствующий код к принятому ответу,

используя parser.set_default():

import argparse

import os

import sys

WIN = sys.platform.startswith('win')
MAC = sys.platform.startswith('darwin')

parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)


parser.set_defaults(osx_frameworks = True,
    jobs = int(os.getenv('JOBS', 0)),
    no_libxml = False,
    no_glut = True,
    use_msgpackc = 'guess',
    testing = False,
    openvr = False,
    use_openmp = 'no' if MAC else 'yes',
    use_vtkm = 'no',
    vmd_plugins = True)

parser.add_argument('--glut', dest='no_glut', action = "store_false",
                    help = "link with GLUT (legacy GUI)")
parser.add_argument('--no-osx-frameworks', dest='osx_frameworks',
                    help = "on MacOS use XQuartz instead of native frameworks",
                    action = "store_false")
parser.add_argument('--jobs', '-j', type=int, help = "for parallel builds "
                    "(defaults to number of processors)")
parser.add_argument('--no-libxml', action = "store_true",
                    help = "skip libxml2 dependency, disables COLLADA export")
parser.add_argument('--use-openmp', choices=('yes', 'no'),
                    help = "Use OpenMP")
parser.add_argument('--use-vtkm', choices=('1.5', '1.6', '1.7', 'no'),
                    help = "Use VTK-m for isosurface generation")
parser.add_argument('--use-msgpackc', choices=('c++11', 'c', 'guess', 'no'),
                    help = "c++11: use msgpack-c header-only library; c: link against "
                    "shared library; no: disable fast MMTF load support")
parser.add_argument('--testing', action = "store_true",
                    help = "Build C-level tests")
parser.add_argument('--openvr', dest='openvr', action='store_true')
parser.add_argument('--no-vmd-plugins', dest='vmd_plugins',
                    action='store_false',
                    help='Disable VMD molfile plugins (libnetcdf dependency)')




options , sys.argv[1:] = parser.parse_known_args()

print('options : ', options )


print('sys.argv[1:] : ',sys.argv[1:])


print('type(options)  :', type(options), options)

for i in dir(options):
    
    if not i.startswith('_'):
        
        try:
   
            print(i ,    '   -----  ' , getattr(options, i) )
            
        except:
            
            print(i, 'errorrrrrrrrr')



print('\n\n\n')

d = vars(options)

print(d)


print('no_glut :',options.no_glut)
print('jobs : ', options.jobs)

или ключевое слово по умолчанию в parser.add_argument:

import argparse

import os

import sys

WIN = sys.platform.startswith('win')
MAC = sys.platform.startswith('darwin')



parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)



parser.add_argument('--glut', dest='no_glut', action = "store_false", default= True,
                    help = "link with GLUT (legacy GUI)")
parser.add_argument('--no-osx-frameworks', dest='osx_frameworks', default=  True  ,
                    help = "on MacOS use XQuartz instead of native frameworks",
                    action = "store_false")
parser.add_argument('--jobs', '-j', type=int, default=  int(os.getenv('JOBS', 0)), help = "for parallel builds "
                    "(defaults to number of processors)")
parser.add_argument('--no-libxml', action = "store_true", default=  False ,
                    help = "skip libxml2 dependency, disables COLLADA export")
parser.add_argument('--use-openmp', choices=('yes', 'no'), default=   'no' if MAC else 'yes',
                    help = "Use OpenMP")
parser.add_argument('--use-vtkm', choices=('1.5', '1.6', '1.7', 'no'), default=  'no' ,
                    help = "Use VTK-m for isosurface generation")
parser.add_argument('--use-msgpackc', choices=('c++11', 'c', 'guess', 'no'), default=  'guess' ,
                    help = "c++11: use msgpack-c header-only library; c: link against "
                    "shared library; no: disable fast MMTF load support")
parser.add_argument('--testing', action = "store_true", default=  False ,
                    help = "Build C-level tests")
parser.add_argument('--openvr', dest='openvr', action='store_true', default= False)
parser.add_argument('--no-vmd-plugins', dest='vmd_plugins',
                    action='store_false', default=  True ,
                    help='Disable VMD molfile plugins (libnetcdf dependency)')


options , sys.argv[1:] = parser.parse_known_args()


print('options : ', options )


print('sys.argv[1:] : ',sys.argv[1:])


print('type(options)  :', type(options), options)

for i in dir(options):
    
    if not i.startswith('_'):
        
        try:
   
            print(i ,    '   -----  ' , getattr(options, i) )
            
        except:
            
            print(i, 'errorrrrrrrrr')


print('\n\n--------------------------------')


d = vars(options)

print(d)


print('no_glut :',options.no_glut)
print('jobs : ', options.jobs)

используя argparser.Namespace для хранения параметров setup.py, конечно, параметры труднее читать в коде, чем в исходной библиотеке, где для их хранения использовался class.

Использование parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) добавляет описание значений по умолчанию в --help.

Другие вопросы по теме