Пытаясь понять 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_args
namespace
?
Обычно тип пространства имен возвращает <class 'argparse.Namespace'>
при использовании этого.
Я получил <class '__main__.Namespace'>
.
Задокументировано ли такое поведение для argparse
, принимают ли ключевые слова namespace
другие типы объектов, которые могут быть полезны для навигации по параметрам предварительной настройки?
Пожалуйста, потерпите меня, я не эксперт в Python, setptools и argparse.
что непонятно. Я спрашивал, правильно ли передавать объект класса в качестве ключевого слова пространства имен в argparser.pares_know_args? Или, если в Python правильно хранить значения как атрибуты класса, я считаю, что если не ошибаюсь, это не считается хорошим программированием на Python. -И мне было интересно, почему пространство имен принимает это и может ли оно принимать другие объекты, такие как словарь и т. д.
ошибки в коде конечно нет
Я вижу три отдельных вопроса, один из которых кажется расплывчатым (что именно представляет собой «эта задача»?), а два из них кажутся второстепенными («задокументировано ли это» и «есть ли еще?», что простирается на слишком широкие рамки). территория). Пожалуйста, сосредоточьтесь на одном, четко определенном вопросе. Возможно, объясните более подробно, что происходит и с каким аспектом вам нужна помощь.
Это предпочтительный/питоновский/правильный способ использования пространства имен parser.parse_known_args?
Вы можете использовать свой собственный класс вместо класса по умолчанию Namespace
, если у вас есть для этого основания. Я удивлен, что вы видите <class '__main__.Namespace'>
в своем коде, я ожидал __main__.options
. Вы уверены, что это репрезентативный результат? Возможно, это ваш вопрос? Кроме того, стоит ли вам использовать свой собственный класс? Если у вас нет причины, нет. Если да, то да.
.... Обычно тип пространства имен возвращает <class 'argparse.Namespace'> при использовании этого... Я не имел в виду этот пример. Если я использую параметры, sys.argv[1:] = parser.parse_known_args(namespace=options) ; тип (опции) — пространство имен. Немного выше.... где в опциях sys.argv[1:] = parser.parse_known_args(namespace=options), пространство имен указывает на класс опций. ---> __main__.options
По сути, это использование экземпляра type
вместо экземпляра argparse.Namespace
для хранения определенных аргументов. Это немного неортодоксально, поскольку определяет класс без намерения создать его экземпляр.
Возможно, более ортодоксальным подходом было бы использовать метод set_defaults
для предоставления значений по умолчанию для различных аргументов, а не инициализировать options
или экземпляр Namespace
вручную.
Да, обычно можно просто использовать поведение по умолчанию 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() ?
Значения по умолчанию для цели используются, если цель не задана иным образом вызовом parse_known_args
.
Здесь просто чтобы попытаться добавить соответствующий код к принятому ответу,
используя 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.
Это не мой минус, но это довольно неясно. Пожалуйста, ознакомьтесь с справочным центром и, в частности, Как спрашивать , а также с инструкциями по предоставлению минимально воспроизводимого примера.