Python

備忘録

公開日: 2025-05-18 更新日: 2025-05-18

環境管理

パッケージマネージャ

$ pip install --outdated
$ pip show {pkg}
$ pip freeze > requirements.txt
$ pip install -r requirements.txt -c constraints.txt

仮想化

$ python -m venv .venv
$ . .venv/bin/activate

便利な言語機能

関数の引数

  • 位置引数
  • キーワード引数
  • 可変長位置引数 … *func
  • 可変長キーワード引数 … **func
  • * … 後に続く引数をキーワード専用引数にする (def func(val1, val2, *, val3) )
  • / … 前の引数を位置専用引数にする

オブジェクト関連

print(id(123))
print(type(123))
print(isinstance(123, int))
print(issubclass(float, object)) ... True
help(int)
print(dir(123))

プロパティ

class Hoge:
    _name = None

    @property
    def name(self):
        return self._name
    @name.setter
    def name(self, val):
        self._name = val

obj = Hoge()
print(obj.name)
obj.name = "hoge"
print(obj.name)

静的メソッド

class Hoge:
    def nyao(self, val):
        Hoge.piyo(val)
    def hell(self, val):
        Hoge.hoge(val)

    @classmethod
    def piyo(cls, val):
        print(f"Called piyo {val}.")

    @staticmethod
    def hoge(val):
        print(f"Called hoge {val}.")

Hoge.hoge(123)
Hoge.piyo(234)
var = Hoge()
var.hell(345)

コンテキストマネージャ

  • __enter__ , __exit__ のメソッドを持つオブジェクト
  • with 句で指定すると楽
import contextlib
@contextlib.contextmanager
def context_manager_sample():
    try:
        print("processing")
        yield "aaa"
    finally:
        print("finalization")

with context_manager_sample() as a:
    print(a)
    pass

テストに便利なもの

使う時に毎回覚えていない類。

DocTest

import doctest

def hoge(x: int):
    """
    hogehoge
    ===========

    >>> hoge(10)
    20
    """
    return x + 10

def fooo():
    """
    >>> fooo()
    Traceback (most recent call last):
    BaseException: hello exception
    """

    # Traceback (innermost last): でも可能
    raise BaseException("hello exception")

if __name__ == "__main__":
    import doctest
    doctest.testmod()

# testmod を呼ばずにCLIから実行する事も可能
# python -m doctest {python script file path}

UnitTest

import unittest

class HogeTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        print("テストクラス単位での事前処理")
        return super().setUpClass()
    
    @classmethod
    def tearDownClass(cls) -> None:
        print("テストクラス単位での事後処理")
        return super().tearDownClass()

    def setUp(self) -> None:
        print("テストごとの事前処理")
        return super().setUp()
    
    def tearDown(self) -> None:
        print("テストごとの事後処理")
        return super().tearDown()

    # テストケースのメソッドは "test~"
    def test_foo1(self):
        val_expect = 123
        val_actual = 123
        self.assertEqual(val_expect, val_actual)

    def test_foo2(self):
        val_expect = 123
        val_actual = 234
        self.assertEqual(val_expect, val_actual)
    
    def test_foo3(self):
        with self.subTest("subtest1", aaa=123, bbb=234):
            self.assertEqual(123, 234)
        with self.subTest("subtest2", aaa=123, bbb=234):
            self.assertEqual(123, 123)
        with self.subTest("subtest3", aaa=123, bbb=234):
            self.assertEqual(123, 234)

# if __name__ == "__main__":
#     unittest.main()

# CLI からも実行可能
# python -m unittest sample.HogeTest.test_foo1

UnitTest.Mock

import unittest
from unittest.mock import Mock, patch
from hogemod import HogeParent

class HogeTest(unittest.TestCase):
    def test_foo01(self):
        mock = Mock(["hoge", "fooo"])
        mock.return_value = 123
        mock.hoge.return_value = "aaa"
        mock.fooo.return_value = "bbb"

        res = mock()
        self.assertEqual(123, res)
        self.assertEqual("aaa", mock.hoge())
        self.assertEqual("bbb", mock.fooo())
    
    def test_foo02(self):
        try:
            mock = Mock()
            mock.side_effect = BaseException
            mock()
        except: pass
        self.assertRaises(BaseException)

    @patch("hogemod.HogeChild1")
    def test_foo03(self, HogeChild1Mock):
        mock_ins = HogeChild1Mock()
        mock_ins.get_value.return_value = 999

        obj = HogeParent()
        res = obj.get_value()
        
        self.assertEqual(999, res)

    def test_foo03(self):
        with patch("hogemod.HogeChild1") as HogeChild1Mock:
            mock_ins = HogeChild1Mock()
            mock_ins.get_value.return_value = 999

            obj = HogeParent()
            res = obj.get_value()
        
        self.assertEqual(999, res)

if __name__ == "__main__":
    unittest.main()

Timeit

import timeit

res = timeit.timeit('print("timeit")', number=10)
print("timeit:", res)

res = timeit.repeat('print("repeat")', number=10, repeat=2)
print("repeat:", res)

res = timeit.Timer('print("Timer")')
res = res.timeit(10)
print("Timer:", res)