3.8.19. 型ヒントの使い方

バージョン 1.6.0 から型ヒントに対応しました. pysimple.typing モジュールで import 可能なオブジェクトは 型ヒント をご覧ください.

3.8.19.1. 基本的な使い方

pysimple モジュールから直接 import できるクラスは,そのまま型ヒントに用いることができます.:

from pysimple import Element

def element_name(i: Element) -> str:
    return i.name

i = Element(value=[1, 2])
print(element_name(i))  # i

pysimple モジュールから直接 import できない一部のクラスは pysimple.typing から import できます.:

from pysimple import Condition
from pysimple.typing import Cond

def cond_name(c: Cond) -> str:
    return c.name

i = Element(value=[1, 2])
c = Condition(i, i>1)  # c: Cond
print(cond_name(c))    # (i, (i>1))

pysimple.typing には基底クラスやエイリアスも含まれています.:

from pysimple import Element, Condition
from pysimple.typing import ELEMENT

def ELEMENT_name(e: ELEMENT) -> str:
    return e.name

i = Element(value=[1, 2])
c = Condition(i, i>1)   # c: Cond
print(ELEMENT_name(i))  # i
print(ELEMENT_name(c))  # (i, (i>1))

IntegerVariableBinaryVariableVariable 型になることにご注意ください.:

from pysimple import Variable, IntegerVariable

def variable_name(v: Variable) -> str:
    return v.name

def ivariable_name(v: IntegerVariable) -> str:
    return v.name

x = IntegerVariable()  # x: Variable
variable_name(x)   # OK
#ivariable_name(x)  # NG

3.8.19.2. 高度な使い方

次の例では Set.__getitem__ の戻り値の型を考えています.:

from typing import reveal_type
from pysimple import Set

# Set.__getitem__(self, key: int) -> DType | Key
I = Set(value=[1, 2])
i0 = I[0]  # int

IJ = Set(value=[(1, 3), (1, 4), (2, 3)])
ij0 = IJ[0]  # tuple[int, int]

Set.__getitem__(int) の戻り値は DType | Key ですが, 実際には Set の次元が 1 のときは DType,2 以上のときは Key となります. これは型チェックでは判定できないため,assert などによって type narrowing を行うことで, 手動で型を絞り込むことができます.:

reveal_type(i0)
reveal_type(ij0)

# type narrowing
assert isinstance(i0, int)
assert isinstance(ij0, tuple)

reveal_type(i0)
reveal_type(ij0)

このような関数,プロパティは他にも Set.next, Set.prev, Parameter.__abs__, Parameter.__ceil__, Parameter.__floor__, dual 属性,pysimple.func などがあります.

次に,チュートリアルの 集合・添字 のようなパターンを見てみましょう.:

from pysimple import Problem, Element, Parameter, Variable

i = Element(value=[0, 1])
j = Element(value=['重油', 'ガス'])

costX = Parameter(index=i, value={0: 180, 1: 160})
norma = Parameter(index=j, value={'重油': 12, 'ガス': 24})
x = Variable(lb=0, ub=5, index=i)

problem = Problem()
problem += costX[0]*x[0] + costX[1]*x[1]
problem += 6*x[0] +   x[1] >= norma['重油']
problem += 4*x[0] + 6*x[1] >= norma['ガス']

ここでは costX[0]*x[0] の部分で型チェッカーがエラーを検出します. これは Parameter は値に数値または文字列をとることができできる一方で, Variable は文字列との積は定義されていないためです.

Parameter の値の型を指定する方法は現在,提供されていないため,例えば typing.cast を使うことで 型エラーを回避できます.:

from typing import cast
:
problem += cast(float, costX[0])*x[0] + cast(float, costX[1])*x[1]