Возможно ли обезьянье поведение фрагмента массива numpy?

#python #arrays #monkeypatching

#python #массивы #обезьянье исправление

Вопрос:

Я знаю, что monkeypatching не одобряется (по уважительной причине), но это будет только в скрипте, с которым никому другому никогда не придется иметь дело. И я хотел бы немного лучше понять Python 🙂

Python не выдает ошибку, если границы фрагмента превышают длину срезаемого объекта. Например:

 >>> 'abc'[10:20]
''
 

Все это прекрасно и хорошо, но что, если вы хотите, чтобы была выдана ошибка? В частности, при использовании массивов Numpy. Я хотел бы иметь что-то вроде

 # This will not work! 
import numpy as np

old_getitem = np.array.__getitem__

def new_getitem(self, val):
    if isinstance(val, slice):
        if val.stop >= len(self):
            raise IndexError
    return old_getitem(self, val)

np.array__getitem__ = new_getitem
 

но это не может работать, поскольку np.array не имеет __getitem__ атрибута

 >>> np.array.__getitem__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__getitem__'
 

что я нахожу странным, так это то, что работает следующее:

 >>> a = np.array([1, 2, 3])
>>> a.__getitem__(slice(0,2))
array([1, 2])
 

Моим первым предположением было бы, что Numpy использует атрибут родительского класса, но (насколько я знаю) у него его нет как ‘builtin_function_or_method’

Итак, у меня есть два вопроса. Возможно ли выполнить мою глупую обезьянью обработку? И почему вызов __getitem__ массива Numpy работает, когда у него нет __getitem__ атрибута?

Комментарии:

1. numpy.array это функция конструктора, а не тип. Тип такой numpy.ndarray (но вы также не можете использовать методы обезьяньего исправления для этого).

2. ах, это объясняет, почему __getitem__ сработало без включения в список. Спасибо 🙂

3. выполнив еще один поиск, я нашел комментарий от Гвидо ван Россума, отвечающий на немного другую ссылку на вопрос, которая добавляет еще несколько слов к «вы не можете изменять атрибуты для встроенных модулей». Я думаю, это общий вывод?