Registrieren Sie Funktionsargumente automatisch in argparse in Python

Einführung

argparse ist ein nützliches Paket zum Erstellen von Befehlszeilenskripten mit optionalen Argumenten in Python. Es ist ein praktisches Paket, aber ich habe Dutzende Male gemacht, um Argumente mit Funktionen fest zu machen und sie erneut mit Argparse zu schreiben, und ich war von dem Gedanken getrieben, dass diese Arbeit nutzlos war. Also lass es uns automatisieren.

Unterschied zum Klick

In dem Kommentar wurde mir gesagt, dass ich das Gleiche wie Klick mache, und ich dachte, ich hätte das Rad für eine Weile neu erfunden, aber als ich versuchte, Klick zu verwenden, scheint es anders zu sein, also werde ich es hinzufügen .. Die Funktion von click besteht darin, dass die Definition von Optionen und Argumenten, die von argparse geschrieben wurden, an jede Funktion als Dekorateur verteilt werden kann und die Argumente der Funktion nicht automatisch als Optionen registriert werden. Schließlich schreiben Sie anstelle von add_argument einfach @ click.option, und der Inhalt, den Sie schreiben, ändert sich nicht so sehr. Das bedeutet nicht, dass das Klicken schlecht ist, es ist ein anderer Zweck. Click ist ein großartiges Paket zum Organisieren und Schreiben sowie zur Verbesserung der Lesbarkeit. Diesmal habe ich es jedoch grob geschrieben, um "alle Argumente der erstellten Funktion automatisch als Befehlszeilenargumente zu registrieren!". Daher kann die folgende Überlegung für ein einfaches, aber variables Skript dennoch nützlich sein. Unbekannt··. Im Gegenteil, ich habe versucht, mit Klick zu arbeiten, und viele Funktionen gefunden, die in anderen Szenen nützlich sein könnten. Deshalb werde ich den Inhalt beim nächsten Mal separat zusammenfassen.

Funktionsargumentanalyse

Ein Paket namens inspect wird für die Analyse von Funktionsargumenten verwendet. Da ich python2.7 verwende, verwende ich die alte getargspec, aber für python3 verwenden Sie getfullargspec.

from inspect import getargspec

def func(aaa=1, bbb="a", ccc=[1,2,3,]):
	pass

args, varargs, keywords, defaults = getargspec(func)

print 'args: ', args
print 'varargs', varargs
print 'keywords: ', keywords
print 'defaults: ', defaults

Wenn ich das oben genannte ausführe, erhalte ich die folgende Ausgabe:

args:  ['aaa', 'bbb', 'ccc']
varargs None
keywords:  None
defaults:  (1, 'a', [1, 2, 3])

Automatische Registrierung von Argumenten zu argparse

Verwenden Sie diese Informationen, um Argparse-Optionen automatisch zu registrieren.

from inspect import getargspec

def func(aaa=1, bbb="a", ccc=[1,2,3,]):
	pass

args, varargs, keywords, defaults = getargspec(func)

import argparse

parser = argparse.ArgumentParser()
for arg, default in zip(args, defaults):
	parser.add_argument(
		'--' + arg,
		default=default,
		type=type(default)
	)

print parser.parse_args()

Wenn Sie die obigen Schritte ausführen, erhalten Sie das folgende Namespace-Objekt:

Namespace(aaa=1, bbb='a', ccc=[1, 2, 3])

Unterstützung für Argumente variabler Länge

Tatsächlich reicht im obigen Fall die Entsprechung zu Argumenten variabler Länge nicht aus. Unten finden Sie den Code, der Argumente für Argumente variabler Länge hinzufügt, obwohl er etwas länger sein wird.

from inspect import getargspec

def func(aaa=1, bbb="a", ccc=[1,2,3,]):
	pass

args, varargs, keywords, defaults = getargspec(func)

import argparse

parser = argparse.ArgumentParser()
for arg, default in zip(args, defaults):
	if type(default) is tuple or type(default) is list:
		parser.add_argument(
			'--' + arg,
			default=default,
			type=type(default),
			nargs='+'
		)
	else:
		parser.add_argument(
			'--' + arg,
			default=default,
			type=type(default)
		)

Wenn das Argument eine Liste oder ein Tapple ist, fügen Sie das Argument nargs zu add_argument hinzu.

Entsprechung zum Bool-Wert, aktivieren, deaktivieren ...

Im Fall eines Bool-Wert-Arguments wird der Wert eindeutig bestimmt, wenn er nicht der Standardwert ist. Daher wird häufig das Akronym disable angegeben, enable anstelle von True, False, um eine Option festzulegen, die keinen Wert annimmt. .. Einschließlich dieser Entsprechung wird es wie folgt.

from inspect import getargspec


def func(aaa=1, bbb="a", ccc=[1,2,3,], ddd=True, eee=False):
	pass

args, varargs, keywords, defaults = getargspec(func)

import argparse

parser = argparse.ArgumentParser()
for arg, default in zip(args, defaults):
	if type(default) is tuple or type(default) is list:
		parser.add_argument(
			'--' + arg,
			default=default,
			type=type(default),
			nargs='+'
		)
	elif type(default) is bool and default:
		parser.add_argument(
			'--disable_' + arg,
			dest=arg,
			default=default,
			action="store_false"
		)
	elif type(default) is bool and not default:
		parser.add_argument(
			'--enable_' + arg,
			dest=arg,
			default=default,
			action="store_true"
		)
	else:
		parser.add_argument(
			'--' + arg,
			default=default,
			type=type(default)
		)

Argumentunterstützung ohne Standardwert

Last but not least werden auch Argumente unterstützt, die keine Standardwerte haben. Beachten Sie jedoch, dass dieses Argument als Zeichenfolge erkannt wird, da sein Typ unbekannt ist.

from inspect import getargspec

def func(x, aaa=1, bbb="a", ccc=[1,2,3,], ddd=True, eee=False):
	pass

args, varargs, keywords, defaults = getargspec(func)

print 'args: ', args
print 'varargs', varargs
print 'keywords: ', keywords
print 'defaults: ', defaults

parser = argparse.ArgumentParser()

while len(args) > len(defaults):
	l = list(defaults)
	l.insert(0, None)
	defaults = tuple(l)
	
for arg, default in zip(args, defaults):
	if default is None:
		parser.add_argument(dest=arg)
	elif type(default) is tuple or type(default) is list:
		parser.add_argument(
			'--' + arg,
			default=default,
			type=type(default),
			nargs='+'
		)
	elif type(default) is bool and default:
		parser.add_argument(
			'--disable_' + arg,
			dest=arg,
			default=default,
			action="store_false"
		)
	elif type(default) is bool and not default:
		parser.add_argument(
			'--enable_' + arg,
			dest=arg,
			default=default,
			action="store_true"
		)
	else:
		parser.add_argument(
			'--' + arg,
			default=default,
			type=type(default)
		)

print parser.parse_args()

Fazit

Durch die Verwendung von inspect und argparse war es möglich, das Argument der Funktion automatisch auf das Argument von argparse zu setzen. Die endgültige Version des Codes ist unten beigefügt.

extract_arguments.py


#!/usr/bin/env python

import argparse
from inspect import getargspec

def set_arguments(parser, func):
	args, varargs, keywords, defaults = getargspec(func)

	print 'args: ', args
	print 'varargs', varargs
	print 'keywords: ', keywords
	print 'defaults: ', defaults

	while len(args) > len(defaults):
		l = list(defaults)
		l.insert(0, None)
		defaults = tuple(l)

	for arg, default in zip(args, defaults):
		if default is None:
			parser.add_argument(dest=arg)
		elif type(default) is tuple or type(default) is list:
			parser.add_argument(
				'--' + arg,
				default=default,
				type=type(default),
				nargs='+'
			)
		elif type(default) is bool and default:
			parser.add_argument(
				'--disable_' + arg,
				dest=arg,
				default=default,
				action="store_false"
			)
		elif type(default) is bool and not default:
			parser.add_argument(
				'--enable_' + arg,
				dest=arg,
				default=default,
				action="store_true"
			)
		else:
			parser.add_argument(
				'--' + arg,
				default=default,
				type=type(default)
			)
	return parser

def func(x, aaa=1, bbb="a", ccc=[1,2,3,], ddd=True, eee=False):
	pass


parser = argparse.ArgumentParser()
parser = set_arguments(parser, func)
print parser.parse_args()

Die folgenden Dekoratoren dienen der Vereinfachung.

register_arguments.py


#!/usr/bin/env python

import argparse
from inspect import getargspec

def register_arguments(parser, func):
	args, varargs, keywords, defaults = getargspec(func)
	while len(args) > len(defaults):
		l = list(defaults)
		l.insert(0, None)
		defaults = tuple(l)

	for arg, default in zip(args, defaults):
		if default is None:
			parser.add_argument(dest=arg)
		elif type(default) is tuple or type(default) is list:
			parser.add_argument(
				'--' + arg,
				default=default,
				type=type(default),
				nargs='+'
			)
		elif type(default) is bool and default:
			parser.add_argument(
				'--disable_' + arg,
				dest=arg,
				default=default,
				action="store_false"
			)
		elif type(default) is bool and not default:
			parser.add_argument(
				'--enable_' + arg,
				dest=arg,
				default=default,
				action="store_true"
			)
		else:
			parser.add_argument(
				'--' + arg,
				default=default,
				type=type(default)
			)
	return parser

def register_argparse(parser):
	def wrapper(f):
		register_arguments(parser, f)
		return f
	return wrapper

if __name__ == '__main__':
	parser = argparse.ArgumentParser()

	@register_argparse(parser)
	def func(x, aaa=1, bbb="a", ccc=[1,2,3,], ddd=True, eee=False):
		pass

	print parser.parse_args()

Wenn das obige ausgeführt wird, wird die folgende Ausgabe ausgegeben.

$ python ./register_argments.py a
Namespace(aaa=1, bbb='a', ccc=[1, 2, 3], ddd=True, eee=False, x='a')

Recommended Posts

Registrieren Sie Funktionsargumente automatisch in argparse in Python
Inklusive Notation im Argument der Python-Funktion
Vorsichtsmaßnahmen beim Festlegen von Standardwerten für Argumente in Python-Funktionsdefinitionen
Über Funktionsargumente (Python)
So empfangen Sie Befehlszeilenargumente in Python
Versuchen Sie automatisch, Enum in Python 3.6 automatisch zu bewerten
Python: Über Funktionsargumente
[Road to Intermediate Python] Definieren Sie die Funktion __getattr__ in der Klasse
Setzen Sie die Schlüsselwortargumente des Konstruktors auf die Scheinattribute in Python
Führen Sie die Python-Funktion von Powershell aus (wie Sie Argumente übergeben).
Erstellen Sie eine Funktion in Python
So löschen Sie stdout in Python
Verwenden Sie die Rückruffunktion in Python
ntile (Dezil) -Funktion in Python
Melden Sie sich auf der Website in Python an
Empfangen Sie Laufzeitargumente in Python 2.7
Wie benutzt man Python Argparse?
Nichtlineare Funktionsmodellierung in Python
Zeichne die Yin-Funktion in Python
Sprechen mit Python [Text zu Sprache]
Sofortige Funktion (Lüge) in Python
Wie man in Python entwickelt
Post an Slack in Python
Erstellen Sie einen Mastodon-Bot mit einer Funktion, die automatisch mit Python antwortet
Wie man aus einer Wahrscheinlichkeitsdichtefunktion in Python tastet
So geben Sie char * in einer Rückruffunktion mit ctypes in Python zurück
Ich habe versucht, die Mail-Sendefunktion in Python zu implementieren
So melden Sie sich mit Python bei AtCoder an und senden automatisch
[Python] Wie man PCA mit Python macht
Implementieren Sie die Funktion power.prop.test von R in Python
Definition des Funktionsargumenttyps in Python
Konvertieren Sie Markdown in Python in PDF
So sammeln Sie Bilder in Python
Formatieren Sie Python-Code automatisch mit Vim
Verwendung von SQLite in Python
Schreiben Sie die AWS Lambda-Funktion in Python
Messen Sie die Ausführungszeit von Funktionen in Python
Im Python-Befehl zeigt Python auf Python3.8
Versuchen Sie, Trace in Python zu berechnen
Versuchen Sie den Zugriff auf das SPS-Register in Python
Wie man MySQL mit Python benutzt
So verpacken Sie C in Python
Verwendung von ChemSpider in Python
6 Möglichkeiten zum Stringen von Objekten in Python
Verwendung von PubChem mit Python
Funktionssynthese und Anwendung in Python
Übergeben Sie Argumente in discord.py an Task
Fügen Sie "%" in die Argparse-Hilfe ein, um zu sterben
Verwendung der Zip-Funktion von Python
Umgang mit Japanisch mit Python
Eine Alternative zu "Pause" in Python
[Python] Funktionsargumente * (Stern) und ** (Doppelstern)
Dinge, auf die Sie achten müssen, wenn Sie Standardargumente in Python verwenden
Übergeben von Argumenten an Python-Skripte in SPSS Modeler Batch
Ich habe eine Funktion zum Laden des Git-Erweiterungsskripts in Python geschrieben
Versuchen Sie, sich mit Python auf Ihrem PC automatisch bei Netflix anzumelden
Ich habe versucht, PLSA in Python zu implementieren
[Einführung in Python] Wie verwende ich eine Klasse in Python?
Versuchen Sie, sich mit Python bei qiita anzumelden