Python組み込み数値型を判定するNumPy C-API関数:int PyArray_IsPythonNumber()のすべて


PyArray_IsPythonNumber() は、NumPy C-API における関数の一つで、引数 opPython の組み込み数値型 に属しているかどうかを判定します。

機能

  • 上記以外の型の場合、0 を返します。
  • op が以下のいずれかの型である場合、1 を返します。
    • int
    • float
    • complex
    • long
    • bool

使い方

#include <numpy/arrayobject.h>

int main() {
  PyObject *obj1 = PyInt_FromLong(10);
  PyObject *obj2 = PyFloat_FromDouble(3.14);
  PyObject *obj3 = PyString_FromString("Hello");

  printf("obj1 is a Python number: %d\n", PyArray_IsPythonNumber(obj1));  // 1 を出力
  printf("obj2 is a Python number: %d\n", PyArray_IsPythonNumber(obj2));  // 1 を出力
  printf("obj3 is a Python number: %d\n", PyArray_IsPythonNumber(obj3));  // 0 を出力

  Py_DECREF(obj1);
  Py_DECREF(obj2);
  Py_DECREF(obj3);

  return 0;
}
  • PyArray_IsPythonNumber() は、NumPy 配列の要素が Python の組み込み数値型かどうかを判定する際に役立ちます。
  • PyArray_IsPythonNumber() は、PyArray_CheckScalar() と似ていますが、PyArray_IsPythonNumber() は Python の組み込み数値型のみを判定し、PyArray_CheckScalar() は NumPy のスカラー型も判定します。

例:NumPy 配列の要素が Python の組み込み数値型かどうかを判定

#include <numpy/arrayobject.h>

int main() {
  npy_intp dims[] = {3};
  PyObject *arr = PyArray_SimpleNewFromInt(1, dims, NPY_INT32);
  if (arr == NULL) {
    return -1;
  }

  PyArray_Scalar *scalar = PyArray_ScalarViewSet(arr, 1, NULL);
  if (scalar == NULL) {
    Py_DECREF(arr);
    return -1;
  }

  int is_python_number = PyArray_IsPythonNumber(scalar->obm);
  printf("Scalar element is a Python number: %d\n", is_python_number);

  PyArray_ScalarDestroy(scalar);
  Py_DECREF(arr);

  return 0;
}

この例では、PyArray_IsPythonNumber() を使って、NumPy 配列 arr の要素が Python の組み込み数値型かどうかを判定しています。



#include <numpy/arrayobject.h>

int main() {
  PyObject *obj1 = PyInt_FromLong(10);
  PyObject *obj2 = PyFloat_FromDouble(3.14);
  PyObject *obj3 = PyString_FromString("Hello");
  PyObject *obj4 = PyList_New(0);
  PyObject *obj5 = PyTuple_New(2);

  printf("obj1 is a Python number: %d\n", PyArray_IsPythonNumber(obj1));
  printf("obj2 is a Python number: %d\n", PyArray_IsPythonNumber(obj2));
  printf("obj3 is a Python number: %d\n", PyArray_IsPythonNumber(obj3));
  printf("obj4 is a Python number: %d\n", PyArray_IsPythonNumber(obj4));
  printf("obj5 is a Python number: %d\n", PyArray_IsPythonNumber(obj5));

  Py_DECREF(obj1);
  Py_DECREF(obj2);
  Py_DECREF(obj3);
  Py_DECREF(obj4);
  Py_DECREF(obj5);

  return 0;
}

このコードは、PyArray_IsPythonNumber() を使って、さまざまなタイプの Python オブジェクトが Python の組み込み数値型かどうかを判定します。

NumPy 配列の要素が Python の組み込み数値型かどうかを判定

#include <numpy/arrayobject.h>

int main() {
  npy_intp dims[] = {3};
  PyObject *arr = PyArray_SimpleNewFromInt(1, dims, NPY_INT32);
  if (arr == NULL) {
    return -1;
  }

  int i;
  for (i = 0; i < PyArray_Size(arr); i++) {
    PyObject *scalar = PyArray_ScalarViewSet(arr, i, NULL);
    if (scalar == NULL) {
      Py_DECREF(arr);
      return -1;
    }

    int is_python_number = PyArray_IsPythonNumber(scalar->obm);
    printf("Element [%d] is a Python number: %d\n", i, is_python_number);

    PyArray_ScalarDestroy(scalar);
  }

  Py_DECREF(arr);

  return 0;
}

ユーザー定義の型を判定

#include <numpy/arrayobject.h>

typedef struct {
  int value;
} MyStruct;

int main() {
  MyStruct s = {10};
  PyObject *obj = PyInt_FromLong(s.value);

  printf("MyStruct object is a Python number: %d\n", PyArray_IsPythonNumber(obj));

  Py_DECREF(obj);

  return 0;
}

このコードは、PyArray_IsPythonNumber() が Python の組み込み数値型のみを判定することを示しています。 ユーザー定義の型 MyStruct は、Python の組み込み数値型ではないため、PyArray_IsPythonNumber()0 を返します。

#include <numpy/arrayobject.h>

int main() {
  PyObject *obj = Py_None;

  if (PyArray_IsPythonNumber(obj) == -1) {
    PyErr_Print();
    return -1;
  }

  int is_python_number = PyArray_IsPythonNumber(obj);
  printf("obj is a Python number: %d\n", is_python_number);

  return 0;
}


PyType_Check() 関数

PyType_Check() 関数は、オブジェクトが特定の型のインスタンスかどうかを判定します。 以下のように使用できます。

#include <Python.h>

int main() {
  PyObject *obj1 = PyInt_FromLong(10);
  PyObject *obj2 = PyFloat_FromDouble(3.14);
  PyObject *obj3 = PyString_FromString("Hello");

  printf("obj1 is an int: %d\n", PyType_Check(obj1, &PyInt_Type));
  printf("obj2 is a float: %d\n", PyType_Check(obj2, &PyFloat_Type));
  printf("obj3 is a str: %d\n", PyType_Check(obj3, &PyString_Type));

  Py_DECREF(obj1);
  Py_DECREF(obj2);
  Py_DECREF(obj3);

  return 0;
}

このコードは、PyType_Check() を使って、obj1int 型、obj2float 型、obj3str 型かどうかを判定しています。

isinstance() 関数

isinstance() 関数は、オブジェクトが特定の型のサブクラスかどうかを判定します。 以下のように使用できます。

#include <Python.h>

int main() {
  PyObject *obj1 = PyInt_FromLong(10);
  PyObject *obj2 = PyFloat_FromDouble(3.14);
  PyObject *obj3 = PyString_FromString("Hello");

  printf("obj1 is a subclass of int: %d\n", isinstance(obj1, (PyTypeObject *)PyInt_Type));
  printf("obj2 is a subclass of float: %d\n", isinstance(obj2, (PyTypeObject *)PyFloat_Type));
  printf("obj3 is a subclass of str: %d\n", isinstance(obj3, (PyTypeObject *)PyString_Type));

  Py_DECREF(obj1);
  Py_DECREF(obj2);
  Py_DECREF(obj3);

  return 0;
}

このコードは、isinstance() を使って、obj1int 型のサブクラス、obj2float 型のサブクラス、obj3str 型のサブクラスかどうかを判定しています。

PyFloat_Check() 関数と PyInt_Check() 関数

PyFloat_Check() 関数は、オブジェクトが float 型かどうかを判定します。 PyInt_Check() 関数は、オブジェクトが int 型かどうかを判定します。 以下のように使用できます。

#include <Python.h>

int main() {
  PyObject *obj1 = PyInt_FromLong(10);
  PyObject *obj2 = PyFloat_FromDouble(3.14);
  PyObject *obj3 = PyString_FromString("Hello");

  printf("obj1 is a float: %d\n", PyFloat_Check(obj1));
  printf("obj2 is a float: %d\n", PyFloat_Check(obj2));
  printf("obj3 is a float: %d\n", PyFloat_Check(obj3));

  printf("obj1 is an int: %d\n", PyInt_Check(obj1));
  printf("obj2 is an int: %d\n", PyInt_Check(obj2));
  printf("obj3 is an int: %d\n", PyInt_Check(obj3));

  Py_DECREF(obj1);
  Py_DECREF(obj2);
  Py_DECREF(obj3);

  return 0;
}

このコードは、PyFloat_Check()PyInt_Check() を使って、obj1float 型かどうか、obj2float 型かどうか、obj3float 型かどうか、obj1int 型かどうか、obj2int 型かどうか、obj3int 型かどうかを判定しています。