【ステップアップ】「Pythonの実践」簡単速習‼【コンフィグとロギング/応用①】

こんにちはヤク学長です。
データサイエンティスト兼ファーマシストで、アルゴリズムやBI開発を行っています。

本記事の目的は、「pythonの基本操作を知る」ことを目的としています。

【やさしい】「Pythonの基礎知識」簡単速習!!【3分で学ぶ/基本①】

【本記事のもくじ】

まず、「Python」に真剣に取り組むための概要を解説します。
下記の方法で、簡単に概要を抑えることができます。

  • 1.コンフィグとロギング

それでは、上から順番に見ていきます。
なお、本上記の方法を順番に抑えれば成果が出ます。

記事の内容は「転載 & 引用OK」問題ありません。

1.コンフィグとロギング

Configparser

コンフィグパーサーは、設定ファイルの形式を解析して、プログラムが読み込みやすい形式に変換するプログラムのことです。設定ファイルは、プログラムの挙動を設定するためのファイルで、例えば、ウェブサーバーのポート番号やデータベースの接続情報などが含まれます。

具体的な例を挙げると、Java言語の場合、Java標準ライブラリには、XML形式の設定ファイルを解析するための「javax.xml.parsers」パッケージがあります。このパッケージを使用することで、XML形式の設定ファイルを解析し、プログラムが読み込みやすい形式に変換することができます。

また、Python言語の場合、標準ライブラリに「configparser」というモジュールがあります。このモジュールを使用することで、INI形式の設定ファイルを解析し、プログラムが読み込みやすい形式に変換することができます。例えば、以下のようなINI形式の設定ファイルを解析することができます。

[database]
host = localhost
port = 3306
user = username
password = password

これらの例からわかるように、コンフィグパーサーは、設定ファイルを解析してプログラムが扱いやすい形式に変換することで、プログラムの設定や動作を柔軟に変更することができます。

yaml

YAMLとは、「YAML Ain’t Markup Language」の略で、構造化データを表現するためのフォーマットの一種です。YAMLは、JSONやXMLと同じように、データのシリアライズに使用されます。

YAMLは、人間が読み書きしやすく、インデントによって階層を表現することができます。以下は、YAMLの例です。

# コメント
menu:
- title: Home
url: /
- title: Products
url: /products
children:
- title: Product 1
url: /product-1
- title: Product 2
url: /product-2
- title: Contact
url: /contact

このYAMLは、メニューの階層構造を表現しています。”menu”は配列で、各要素には”title”と”url”のフィールドがあります。”Products”の要素には”children”というフィールドがあり、その下にも階層があります。

YAMLは、多くのプログラミング言語で扱うことができます。Pythonでは、PyYAMLというパッケージを使うことで、YAMLを読み書きすることができます。例えば、以下のようなコードで、上記のYAMLを読み込んで、JSON形式に変換することができます。

import yaml
import json
yaml_str = """
menu:
- title: Home
url: /
- title: Products
url: /products
children:
- title: Product 1
url: /product-1
- title: Product 2
url: /product-2
- title: Contact
url: /contact
"""
data = yaml.safe_load(yaml_str)
json_str = json.dumps(data)
print(json_str)

このコードを実行すると、以下のようなJSONが出力されます。

{"menu": [{"title": "Home", "url": "/"}, {"title": "Products", "url": "/products", "children": [{"title": "Product 1", "url": "/product-1"}, {"title": "Product 2", "url": "/product-2"}]}, {"title": "Contact", "url": "/contact"}]}

ロギング

ロギング (Logging) とは、アプリケーションの実行時に発生する情報(ログ)を収集し、保存、表示、解析することで、アプリケーションの問題解決やデバッグを支援するための技術です。ログには、実行時の情報やエラーメッセージ、スタックトレースなどが含まれます。

ロギングを実現するために、多くのプログラミング言語には、ロギングライブラリが用意されています。ロギングライブラリを使用することで、ログを様々な形式で出力したり、ログレベルに応じたフィルタリングを行ったりすることができます。

ロギングにおいては、ログレベルという概念があります。ログレベルには、以下のようなものがあります。

  • DEBUG:デバッグ情報
  • INFO:情報
  • WARNING:警告
  • ERROR:エラー
  • CRITICAL:致命的なエラー

ログレベルによって、出力するログの詳細度を調整することができます。たとえば、デバッグ時にはDEBUGレベルでログを出力し、本番環境ではERROR以上のレベルのログのみを出力するなどの設定が可能です。

Pythonでは、標準ライブラリのloggingモジュールを使用することで、ロギングを実現することができます。以下は、loggingモジュールを使用したロギングの例です。

import logging

# ログの出力先やフォーマットを設定
logging.basicConfig(level=logging.DEBUG, filename='app.log', format='%(asctime)s %(levelname)s: %(message)s')

# ログの出力
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')

この例では、ログレベルをDEBUGに設定し、ログの出力先をファイルに指定しています。また、ログのフォーマットも設定しています。最後に、各レベルでログを出力しています。ログの出力結果は、指定したファイルに保存されます。

ロギング フォーマッタ

ロギング (Logging) において、フォーマッタ (Formatter) とは、ログの出力形式を指定するためのものです。具体的には、ログのメッセージや日時、ログレベルなどを指定したフォーマットに従って整形することができます。

Pythonのloggingモジュールでは、標準のフォーマットを使用することもできますが、独自のフォーマットを指定することもできます。以下は、独自のフォーマットを使用した例です。

import logging

# ログの出力先をコンソールに指定し、フォーマットを設定
console_handler = logging.StreamHandler()
console_handler.setFormatter(logging.Formatter('%(asctime)s [%(levelname)s] %(message)s'))
# ログの出力先にコンソールを追加
logger = logging.getLogger(__name__)
logger.addHandler(console_handler)

# ログの出力
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')

この例では、ログの出力先をコンソールに指定し、フォーマットを'%(asctime)s [%(levelname)s] %(message)s'という形式で設定しています。このフォーマットでは、%(asctime)sはログの発生日時、[%(levelname)s]はログレベル、%(message)sはログのメッセージを表します。最後に、各レベルでログを出力しています。

このように、フォーマッタを使用することで、ログの出力形式を自由にカスタマイズすることができます。

ロギング ロガー

ロギング (Logging) において、ロガー (Logger) とは、ログを出力するためのオブジェクトです。ロガーは、logging.getLogger()メソッドを使用して取得することができます。

ロガーを使用すると、ログの出力先やフォーマット、ログレベルなどを細かく設定することができます。例えば、以下のようにロガーを使用してログを出力することができます。

import logging

# ロガーを取得
logger = logging.getLogger(__name__)
# ログの出力先やフォーマットを設定
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(asctime)s [%(levelname)s] %(message)s'))
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)

# ログの出力
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')

この例では、ロガーを取得した後、ログの出力先としてコンソールを指定し、フォーマットを設定しています。また、ログレベルをDEBUGに設定しています。最後に、各レベルでログを出力しています。

ロガーは、複数の場所で使用することができます。たとえば、複数のモジュールで使用するロガーを共通のものにすることができます。この場合、同じ名前でロガーを取得することで、同じロガーオブジェクトを使用することができます。ただし、ロガー名は通常、__name__を使用することが推奨されています。

ロギング ハンドラー

ロギング (Logging) において、ハンドラー (Handler) とは、ログを出力する先を指定するオブジェクトです。ハンドラーは、logging.StreamHandlerlogging.FileHandlerなどのクラスを使用して生成することができます。

ハンドラーを使用することで、ログを複数の出力先に出力したり、ログをファイルに書き出したりすることができます。以下は、コンソールとファイルにログを出力する例です。

import logging

# ロガーを取得
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# コンソールに出力するハンドラーを作成
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_handler.setFormatter(logging.Formatter('%(asctime)s [%(levelname)s] %(message)s'))

# ファイルに出力するハンドラーを作成
file_handler = logging.FileHandler('example.log')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(logging.Formatter('%(asctime)s [%(levelname)s] %(message)s'))
# ハンドラーをロガーに追加
logger.addHandler(console_handler)
logger.addHandler(file_handler)

# ログの出力
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')

この例では、logging.StreamHandlerlogging.FileHandlerを使用して、それぞれコンソールとファイルにログを出力するためのハンドラーを作成しています。ハンドラーには、それぞれログレベルやフォーマットを設定しています。また、ハンドラーをロガーに追加しています。

このように、ハンドラーを使用することで、ログの出力先を柔軟に設定することができます。

ロギング フィルタ

ロギング (Logging) において、フィルタ (Filter) とは、ログを出力する前に、特定の条件に基づいてログを制御するためのオブジェクトです。フィルタは、logging.Filterクラスを継承して作成することができます。

フィルタを使用することで、ログレコードが出力される前に、特定の条件に合致するかどうかを判断することができます。例えば、以下のように、特定のレベル以上のログレコードだけを出力するフィルタを作成することができます。

import logging

class LevelFilter(logging.Filter):
def __init__(self, level):
super().__init__()
self.level = level

def filter(self, record):
return record.levelno >= self.level
# ロガーを取得
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# コンソールに出力するハンドラーを作成
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(asctime)s [%(levelname)s] %(message)s'))
handler.addFilter(LevelFilter(logging.WARNING))
# ハンドラーをロガーに追加
logger.addHandler(handler)

# ログの出力
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')

この例では、LevelFilterクラスを定義して、特定のレベル以上のログレコードだけを出力するフィルタを作成しています。filterメソッドでは、レコードのレベルが指定されたレベル以上である場合にTrueを返すように実装されています。また、ハンドラーには、addFilterメソッドを使用して、フィルタを追加しています。

このように、フィルタを使用することで、出力されるログレコードを制御することができます。

ロギング コンフィグ

ロギング (Logging) において、コンフィグ (Config) とは、ログの設定を行うための方法の1つで、設定ファイルや辞書形式のオブジェクトを使用してログの設定を行います。

コンフィグを使用する場合、以下の手順で設定を行います。

  • ロガーを取得する
  • 設定オブジェクトからハンドラーやフォーマッター、フィルターなどのオブジェクトを生成し、ロガーに設定する
  • ロガーを使用してログを出力する

以下は、YAML形式の設定ファイルを使用して、ロギングの設定を行う例です。

version: 1
formatters:
simple:
format: '%(asctime)s [%(levelname)s] %(message)s'
handlers:
console:
class: logging.StreamHandler
level: INFO
formatter: simple
stream: ext://sys.stdout
loggers:
example:
level: DEBUG
handlers: [console]
propagate: no
root:
level: WARNING
handlers: [console]

この例では、logging.config.dictConfig関数を使用して、YAML形式の設定ファイルからログの設定を行っています。設定ファイルには、フォーマッター、ハンドラー、ロガー、ルートロガーの設定が含まれています。具体的には、simpleフォーマッターを定義し、consoleハンドラーを定義して、コンソールにログを出力するように設定しています。

また、exampleロガーにはconsoleハンドラーを追加して、DEBUGレベル以上のログを出力するように設定しています。rootロガーには、WARNINGレベル以上のログを出力するように設定しています。

このように、コンフィグを使用することで、複数のロガー、ハンドラー、フォーマッター、フィルターなどを簡単に設定することができます。

ロギングの書き方

Pythonにおけるロギング (Logging) の書き方には、以下のような手順があります。

  • ロガーを作成する

ロガーは、ログの発生元を識別するためのオブジェクトです。logging.getLogger()関数を使用して、ロガーを作成します。ロガー名を指定しなかった場合、ルートロガーが返されます。

import logging
logger = logging.getLogger('myapp')
  • ロギングレベルを設定する

ログには、DEBUG、INFO、WARNING、ERROR、CRITICALの5つのレベルがあります。logger.setLevel()メソッドを使用して、出力するログの最低レベルを設定します。この設定よりも低いレベルのログは、出力されません。

logger.setLevel(logging.DEBUG)
  • ハンドラーを作成する

ハンドラーは、ログの出力先を指定するオブジェクトです。logging.StreamHandler()を使用して、標準出力やファイルなどの出力先を指定するハンドラーを作成します。

handler = logging.StreamHandler()
  • ハンドラーにフォーマッターを設定する

フォーマッターは、ログの出力形式を指定するオブジェクトです。logging.Formatter()を使用して、ログの出力形式を指定するフォーマッターを作成します。作成したフォーマッターを、先ほど作成したハンドラーに設定します。

formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')
handler.setFormatter(formatter)
  • ロガーにハンドラーを追加する

先ほど作成したハンドラーを、ロガーに追加します。複数のハンドラーを追加することもできます。

logger.addHandler(handler)
  • ログを出力する

ログを出力するには、logger.debug()logger.info()logger.warning()logger.error()logger.critical()メソッドを使用します。

logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')

以上が、Pythonにおけるロギングの書き方の基本的な手順です。より詳しい設定方法については、ロギングの各要素であるフォーマッター、ハンドラー、フィルターなどについて学習する必要があります。

Email送信

PythonでEmailを送信するためには、以下の手順を踏みます。

  • 必要なライブラリをインポートする

Pythonには、Emailを送信するために必要な標準ライブラリemailと、SMTPサーバーに接続するための標準ライブラリsmtplibがあります。それらをインポートします。

import smtplib
from email.mime.text import MIMEText
from email.utils import formatdate
  • メールの内容を作成する

メールの内容を作成し、MIMEText()オブジェクトとして格納します。必要に応じて、件名や差出人、宛先なども指定できます。

subject = 'メールの件名'
body = 'メールの本文'
from_address = '差出人のメールアドレス'
to_address = '宛先のメールアドレス'
msg = MIMEText(body)
msg['Subject'] = subject
msg['From'] = from_address
msg['To'] = to_address
msg['Date'] = formatdate(localtime=True)
  • SMTPサーバーに接続する

SMTPサーバーに接続し、認証情報を設定します。GmailのSMTPサーバーを使う場合は、以下のように設定します。Googleアカウントのパスワードは、アプリパスワードを作成して使用することを推奨します。

smtp_host = 'smtp.gmail.com'
smtp_port = 587
smtp_user = '差出人のメールアドレス'
smtp_password = '差出人のパスワード'
smtpobj = smtplib.SMTP(smtp_host, smtp_port)
smtpobj.starttls()
smtpobj.login(smtp_user, smtp_password)
  • メールを送信する

作成したメッセージオブジェクトを、sendmail()メソッドを使用して送信します。第1引数には、差出人のメールアドレス、第2引数には、宛先のメールアドレス、第3引数には、メール本文を指定します。

smtpobj.sendmail(from_address, [to_address], msg.as_string())
  • SMTPサーバーから切断する

メールの送信が完了したら、quit()メソッドを使用してSMTPサーバーから切断します。

smtpobj.quit()

以上が、PythonでEmailを送信する基本的な手順です。また、SMTPサーバーに接続する前に、ネットワークの状況やSMTPサーバーの設定に応じて必要な設定を行うこともあります。

添付ファイルのEmail送信

Pythonで添付ファイル付きのEmailを送信するためには、email.mime.multipartを使用して、MIMEマルチパートメッセージを作成する必要があります。

以下は、添付ファイル付きのEmailを送信するための基本的な手順です。

  • 必要なライブラリをインポートする

Pythonには、Emailを送信するために必要な標準ライブラリemailと、SMTPサーバーに接続するための標準ライブラリsmtplibがあります。それらをインポートします。

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.utils import formatdate
  • メールの内容を作成する

MIMEマルチパートメッセージを作成し、必要なパラメータを設定します。件名や差出人、宛先などを指定することができます。また、MIMEApplication()オブジェクトを使用して、添付ファイルを作成し、メッセージに追加します。

subject = 'メールの件名'
body = 'メールの本文'
from_address = '差出人のメールアドレス'
to_address = '宛先のメールアドレス'
file_path = '添付ファイルのパス'
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = from_address
msg['To'] = to_address
msg['Date'] = formatdate(localtime=True)

msg.attach(MIMEText(body))

with open(file_path, 'rb') as f:
attachment = MIMEApplication(f.read(), _subtype='pdf')
attachment.add_header('Content-Disposition', 'attachment', filename='sample.pdf')
msg.attach(attachment)
  • SMTPサーバーに接続する

SMTPサーバーに接続し、認証情報を設定します。GmailのSMTPサーバーを使う場合は、以下のように設定します。Googleアカウントのパスワードは、アプリパスワードを作成して使用することを推奨します。

smtp_host = 'smtp.gmail.com'
smtp_port = 587
smtp_user = '差出人のメールアドレス'
smtp_password = '差出人のパスワード'
smtpobj = smtplib.SMTP(smtp_host, smtp_port)
smtpobj.starttls()
smtpobj.login(smtp_user, smtp_password)
  • メールを送信する

作成したメッセージオブジェクトを、sendmail()メソッドを使用して送信します。第1引数には、差出人のメールアドレス、第2引数には、宛先のメールアドレスのリスト、第3引数には、メッセージの文字列を指定します。また、quit()メソッドを使用して、SMTPサーバーとの接続を解除します。

smtpobj.sendmail(from_address, [to_address], msg.as_string())
smtpobj.quit()

以上が、Pythonで添付ファイル付きのEmailを送信する基本的な手順です。

SMTPハンドラーでログをEmail送信

Pythonの標準ライブラリに含まれるlogging.handlers.SMTPHandlerを使用することで、ログをEmailで送信することができます。

SMTPHandlerは、指定したログレベル以上のログを、指定したメールアドレス宛に送信します。以下は、SMTPHandlerを使用してloggerオブジェクトで出力されたログをEmailで送信する例です。

import logging.handlers

# SMTPサーバーの設定
MAIL_HOST = 'smtp.example.com'
MAIL_PORT = 587
MAIL_USERNAME = 'username'
MAIL_PASSWORD = 'password'
FROM_ADDRESS = 'from@example.com'
TO_ADDRESS = 'to@example.com'
# ロガーの設定
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# SMTPハンドラーの設定
handler = logging.handlers.SMTPHandler(
mailhost=(MAIL_HOST, MAIL_PORT),
credentials=(MAIL_USERNAME, MAIL_PASSWORD),
fromaddr=FROM_ADDRESS,
toaddrs=[TO_ADDRESS],
subject='Error log'
)
handler.setLevel(logging.ERROR)

logger.addHandler(handler)

# ログの出力
logger.debug('This is a debug message.')
logger.info('This is an informational message.')
logger.warning('This is a warning message.')
logger.error('This is an error message.')
logger.critical('This is a critical message.')

上記の例では、ログレベルがERROR以上のログを送信するように設定されています。SMTPHandlerをインスタンス化する際に、mailhost引数でSMTPサーバーのホスト名とポート番号、credentials引数でSMTPサーバーに接続するための認証情報、fromaddr引数で差出人のメールアドレス、toaddrs引数で宛先のメールアドレスのリストを指定します。

SMTPHandlerは、ログ出力ごとにSMTPサーバーとの接続を確立するため、頻繁にログを出力する場合は、パフォーマンスに影響がある場合があります。そのため、定期的なログ送信を行うように設定することが推奨されています。

virtualenv

virtualenvは、Pythonプログラムを開発する際に、プロジェクトごとに独立したPython環境を構築するためのツールです。virtualenvを使用することで、複数のプロジェクトで異なるバージョンのPythonパッケージを使用することができます。

以下は、virtualenvを使用して新しい仮想環境を作成する手順です。

  • virtualenvをインストールする

virtualenvを使用するには、まずpipを使用してvirtualenvをインストールする必要があります。

$ pip install virtualenv
  • 仮想環境を作成する

virtualenvを使用して、新しい仮想環境を作成します。以下の例では、myenvという名前の新しい仮想環境を作成しています。

$ virtualenv myenv
  • 仮想環境を有効化する

新しい仮想環境を使用するためには、仮想環境を有効化する必要があります。以下の例では、myenvという名前の仮想環境を有効化しています。

$ source myenv/bin/activate

仮想環境を有効化すると、ターミナルのプロンプトが変わります。有効化された仮想環境でPythonを実行すると、myenvにインストールされたPythonパッケージが使用されます。

  • パッケージをインストールする

有効化された仮想環境で、pipを使用してPythonパッケージをインストールすることができます。

$ pip install package_name
  • 仮想環境を無効化する

仮想環境を使用しなくなった場合は、以下のコマンドで仮想環境を無効化できます。

$ deactivate

以上が、virtualenvを使用して新しい仮想環境を作成する基本的な手順です。仮想環境を使用することで、Pythonプログラムの依存関係を解決し、プロジェクトごとに独立したPython環境を構築することができます。

optparse

optparseは、Pythonプログラムでコマンドライン引数を解析するための標準ライブラリです。optparseを使用すると、プログラムの実行時に引数を指定することができます。

以下は、optparseを使用してコマンドライン引数を解析するための基本的な手順です。

  • optparseをインポートする

optparseを使用するには、まずoptparseをインポートする必要があります。

import optparse
  • OptionParserオブジェクトを作成する

OptionParserオブジェクトを作成し、引数を設定します。

parser = optparse.OptionParser()
parser.add_option('-f', '--file', dest='filename', help='input file name')

上記の例では、-f--fileという2つの引数を定義し、destで受け取る変数名をfilenameとしています。helpは、引数の説明を追加するためのオプションです。

  • 引数をパースする

引数をパースするには、parse_args()メソッドを呼び出します。

(options, args) = parser.parse_args()

optionsは、引数の値を格納するためのオブジェクトであり、argsは、パースされなかった引数を格納するリストです。

  • 引数の値を使用する

optionsオブジェクトを使用して、引数の値を取得することができます。

if options.filename:
print('input file name:', options.filename)

上記の例では、filename引数の値がNoneでない場合、ファイル名を出力するという処理を行っています。

以上が、optparseを使用してコマンドライン引数を解析する基本的な手順です。optparseは、Python 2.xで標準ライブラリとして提供されていますが、Python 3.xではargparseという標準ライブラリに置き換えられています。


というわけで、今回は以上です。大変お疲れさまでした。
引き続きで、徐々に発信していきます。

コメントや感想を受け付けています。ちょっとした感想でもいいので嬉しいです。

それでは、以上です。

最新情報をチェックしよう!