Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

たらららん♪† typeを拡張するコード †たらららん♪

OOな人がpythonにくるといろいろ追加したくなる事があるだろうということで。
ほんのちょっとだけあらびきな方法です。

  1. 追加のみのサポート
  2. 更新、削除はできない(元を書き換えると副作用で何が起こるかわからないから)

決して更新がめんどくさいからじゃないよ!
既存を書き換えてへんてこになるのを防ぐためだよ!

#include <Python.h>

static PyMethodDef EvilMethods[] = { 
    {NULL, NULL, 0, NULL} /* Sentinel */ 
}; 
        
static int
type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
{
	if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0)
		return -1;
	return 0;
}

PyMODINIT_FUNC 
inittypeext(void) 
{ 
    PyObject *m; 
    PyTypeObject *typetype;

    m = Py_InitModule("typeext", EvilMethods); 
    typetype = &PyType_Type;
    typetype->tp_setattro = type_setattro;
}

更新禁止なので一発勝負になる。

>>> a =
>>> a

>>> a.a = 1
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'list' object has no attribute 'a'
>>> list.a = 1
Traceback (most recent call last):
File "", line 1, in
TypeError: can't set attributes of built-in/extension type 'list'
>>> import typeext
>>> list.a = 1
>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'a', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> a.a
1
>>> list.a = 10
>>> list.a
1
>>> a.a
1

まあ誰でもすぐ思いつくよねー。