Da ich häufig Skripte für die Arbeit in Python schreibe, werde ich den Vorlagencode als Memorandum veröffentlichen.
Diese Vorlage führt Folgendes aus:
app_home/
├ bin/
│ └ my_batch.py #← Skript zum Ausführen
├ conf/
│ └ my_batch_conf.py #← Klasse einstellen
├ lib/
│ ├ __init__.py #← Erforderlich zum Laden des Moduls
│ └ my_lib.py #← Bibliothek
├ tests/
│ └ test_my_lib.py #← Unit-Testcode
├ log/ #← Ausgabeziel protokollieren
└ Pipfile #← Listen Sie die zu verwendenden Bibliotheken auf
Inhalt des Hauptteils my_batch.py
import sys
import os
import click
import logging
#Das übergeordnete Verzeichnis ist die Startseite der Anwendung(${app_home})Einstellen
app_home = os.path.abspath(os.path.join( os.path.dirname(os.path.abspath(__file__)) , ".." ))
# ${app_home}Zum Ladepfad der Bibliothek
sys.path.append(os.path.join(app_home))
#Laden Sie Ihre eigene Bibliothek
from lib.my_lib import MyLib
#Konfigurationsklasse laden
from conf.my_batch_conf import MyBatchConf
#Behandlung von Befehlszeilenargumenten. must_arg ist eine erforderliche Option, optional_arg ist optional
@click.command()
@click.option('--must_arg','-m',required=True)
@click.option('--optional_arg','-o',default="DefaultValue")
def cmd(must_arg,optional_arg):
#Programmname ohne Erweiterung vom eigenen Namen(${prog_name})Zu
prog_name = os.path.splitext(os.path.basename(__file__))[0]
#Logger-Einstellungen
#Format
log_format = logging.Formatter("%(asctime)s [%(levelname)8s] %(message)s")
#Niveau
logger = logging.getLogger()
logger.setLevel(logging.INFO)
#Handler zur Standardausgabe
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setFormatter(log_format)
logger.addHandler(stdout_handler)
#Handler zum Protokollieren der Datei
file_handler = logging.FileHandler(os.path.join(app_home,"log", prog_name + ".log"), "a+")
file_handler.setFormatter(log_format)
logger.addHandler(file_handler)
#Starten Sie die Verarbeitung
try:
#Protokollausgabe
logger.info("start")
#Verwendung von Befehlszeilenargumenten
logger.error(f"must_arg = {must_arg}")
logger.error(f"optional_arg = {optional_arg}")
#Bibliotheksaufruf
mylib = MyLib()
logger.info(mylib.get_name())
#Verwendung von Sollwerten
logger.info(MyBatchConf.key1)
logger.info(MyBatchConf.key2)
#Auch wenn eine Ausnahme auftritt ...
raise Exception("My Exception")
except Exception as e:
#Ausnahmen abfangen und protokollieren
logger.exception(e)
sys.exit(1)
if __name__ == '__main__':
cmd()
Inhalt der Konfigurationsklasse conf / my_batch_conf.py
class MyBatchConf(object):
key1 = "key1_value"
key2 = True
*) Früher habe ich configParser verwendet, aber die config-Klasse muss nicht analysiert werden, und die IDE ergänzt sie, sodass ich sie nicht mehr verwende.
Inhalt der Bibliothek my_lib.py
class MyLib(object):
def get_name(self):
return "my_lib"
Inhalt des Testcodes der Bibliothekseinheit test_my_lib.py
import sys,os
import unittest
# ../Fügen Sie lib in den Ladepfad ein
app_home = os.path.abspath(os.path.join( os.path.dirname(os.path.abspath(__file__)) , ".." ))
sys.path.append(os.path.join(app_home,"lib"))
# ../Laden der zu testenden Bibliothek
from my_lib import MyLib
class TestMyLib(unittest.TestCase):
def test_get_name(self):
ml = MyLib()
self.assertEqual("my_lib", ml.get_name())
if __name__ == '__main__':
unittest.main()
Ohne Angabe eines Arguments ausführen
$ python bin/my_batch.py
Ausführungsergebnis (Handbuch erscheint durch Klickfunktion)
Usage: my_batch.py [OPTIONS]
Try "my_batch.py --help" for help.
Error: Missing option "--must_arg" / "-m".
Mit Argumenten ausführen
$ python bin/my_batch.py -m SpecifiedValue
Ausführungsergebnis
2019-06-28 16:42:53,335 [ INFO] start
2019-06-28 16:42:53,335 [ ERROR] must_arg = SpecifiedValue
2019-06-28 16:42:53,335 [ ERROR] optional_arg = DefaultValue
2019-06-28 16:42:53,335 [ INFO] my_lib
2019-06-28 16:42:53,336 [ INFO] key1_value
2019-06-28 16:42:53,336 [ INFO] True
2019-06-28 16:42:53,336 [ ERROR] My Exception
Traceback (most recent call last):
File "bin/my_batch.py", line 62, in cmd
raise Exception("My Exception")
Exception: My Exception
Der gleiche Inhalt wird in das Protokoll ausgegeben (log / my_batch.log)
2019-06-28 16:42:53,335 [ INFO] start
2019-06-28 16:42:53,335 [ ERROR] must_arg = SpecifiedValue
2019-06-28 16:42:53,335 [ ERROR] optional_arg = DefaultValue
2019-06-28 16:42:53,335 [ INFO] my_lib
2019-06-28 16:42:53,336 [ INFO] key1_value
2019-06-28 16:42:53,336 [ INFO] True
2019-06-28 16:42:53,336 [ ERROR] My Exception
Traceback (most recent call last):
File "bin/my_batch.py", line 62, in cmd
raise Exception("My Exception")
Exception: My Exception
Unit-Test ausführen
bash-3.2$ python tests/test_my_lib.py
Ausführungsergebnis
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Tests Der gesamte unten stehende Testcode test_ * .py
wird sofort ausgeführt
$ python -m unittest discover tests "test_*.py"
Dieser Code ist auch auf github → https://github.com/fetaro/python-batch-template-for-v3 verfügbar
Diese Vorlage führt Folgendes aus:
Unterschied zur Python3-Serie
# - * - Codierung: utf-8 - * -
ist am Anfang der Datei erforderlich (da der Quellcode Japanisch enthält)app_home/
├ bin/
│ └ my_batch.py #← Skript zum Ausführen
├ conf/
│ └ my_batch.conf #← Datei einstellen
├ lib/
│ ├ __init__.py #← Erforderlich zum Laden des Moduls
│ └ my_lib.py #← Bibliothek
├ tests/
│ └ test_my_lib.py#← Unit-Testcode
└ log/ #← Ausgabeziel protokollieren
Inhalt von my_batch.py
# -*- coding: utf-8 -*-
import sys
import os
from optparse import OptionParser
from ConfigParser import ConfigParser
import logging
#Das übergeordnete Verzeichnis ist die Startseite der Anwendung(${app_home})Einstellen
app_home = os.path.abspath(os.path.join( os.path.dirname(os.path.abspath(__file__)) , ".." ))
# ${app_home}/Fügen Sie lib zum Ladepfad der Bibliothek hinzu
sys.path.append(os.path.join(app_home,"lib"))
#Laden Sie Ihre eigene Bibliothek
from my_lib import MyLib
if __name__ == "__main__" :
#Programmname ohne Erweiterung vom eigenen Namen(${prog_name})Zu
prog_name = os.path.splitext(os.path.basename(__file__))[0]
#Optionale Perspektive
usage = "usage: %prog (Argument-1) [options]"
parser = OptionParser(usage=usage)
parser.add_option("-d", "--debug",dest="debug", action="store_true", help="debug", default=False)
#Speichern Sie Optionen und Argumente separat
(options, args) = parser.parse_args()
#Argumentprüfung
if len(args) != 1:
sys.stderr.write("argument error. use -h or --help option\n")
sys.exit(1)
#Lesen Sie die Konfigurationsdatei
config = ConfigParser()
conf_path = os.path.join(app_home,"conf", prog_name + ".conf")
config.read(conf_path)
#Logger-Einstellungen
#Format
log_format = logging.Formatter("%(asctime)s [%(levelname)8s] %(message)s")
#Niveau
logger = logging.getLogger()
logger.setLevel(logging.INFO)
#Handler zur Standardausgabe
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setFormatter(log_format)
logger.addHandler(stdout_handler)
#Handler zum Protokollieren der Datei
file_handler = logging.FileHandler(os.path.join(app_home,"log", prog_name + ".log"), "a+")
file_handler.setFormatter(log_format)
logger.addHandler(file_handler)
#Starten Sie die Verarbeitung
try:
#Protokollausgabe
logger.info("start")
logger.error("arg1 = {0}".format(args[0]))
#Optionen abrufen
logger.info(options.debug)
#Bibliotheksaufruf
mylib = MyLib()
logger.info(mylib.get_name())
#Einstellwert lesen
logger.info(config.get("section1","key1"))
logger.info(config.getboolean("section2","key2"))
#Auch wenn eine Ausnahme auftritt ...
raise Exception("My Exception")
except Exception as e:
#Ausnahmen abfangen und protokollieren
logger.exception(e)
sys.exit(1)
Inhalt von my_batch.conf
[section1]
key1 = key1_value
[section2]
key2 = true
Inhalt von my_lib.py
class MyLib(object):
def get_name(self):
return "my_lib"
Inhalt des Unit-Test-Codes test_my_lib.py
# -*- coding: utf-8 -*-
import sys,os
import unittest
# ../Fügen Sie lib in den Ladepfad ein
app_home = os.path.abspath(os.path.join( os.path.dirname(os.path.abspath(__file__)) , ".." ))
sys.path.append(os.path.join(app_home,"lib"))
# ../Laden der zu testenden Bibliothek
from my_lib import MyLib
class TestMyLib(unittest.TestCase):
def test_get_name(self):
ml = MyLib()
self.assertEqual("my_lib", ml.get_name())
if __name__ == '__main__':
unittest.main()
bash-3.2$ python bin/my_batch.py argument1
2016-08-16 23:25:03,492 [ INFO] start
2016-08-16 23:25:03,492 [ ERROR] arg1 = argument1
2016-08-16 23:25:03,492 [ INFO] False
2016-08-16 23:25:03,492 [ INFO] my_lib
2016-08-16 23:25:03,492 [ INFO] key1_value
2016-08-16 23:25:03,492 [ INFO] True
2016-08-16 23:25:03,492 [ ERROR] My Exception
Traceback (most recent call last):
File "bin/my_batch.py", line 73, in <module>
raise Exception("My Exception")
Exception: My Exception
Inhalt des Protokolls (log / my_batch.log)
2016-08-16 23:25:03,492 [ INFO] start
2016-08-16 23:25:03,492 [ ERROR] arg1 = argument1
2016-08-16 23:25:03,492 [ INFO] False
2016-08-16 23:25:03,492 [ INFO] my_lib
2016-08-16 23:25:03,492 [ INFO] key1_value
2016-08-16 23:25:03,492 [ INFO] True
2016-08-16 23:25:03,492 [ ERROR] My Exception
Traceback (most recent call last):
File "bin/my_batch.py", line 73, in <module>
raise Exception("My Exception")
Exception: My Exception
Ergebnis der Unit-Test-Ausführung
bash-3.2$ python tests/test_my_lib.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Tests Beim gleichzeitigen Testen aller Testcodes test_ *. Py
unter den folgenden Bedingungen
bash-3.2$ python -m unittest discover tests "test_*.py"
Der Inhalt dieser Datei wird auch auf github veröffentlicht. Bitte machen Sie, was Sie wollen → https://github.com/fetaro/python-batch-template
Recommended Posts