2

Я создал подкласс ndarray, называемый «Parray», который принимает два аргумента: p и размерность. Он отлично работает сам по себе. Теперь я хочу, чтобы создать класс под названием SirPlotsAlot, который наследуется PArray без всего фантазии новый и array_finalize т.д.numpy subclass не принимает аргументы для __new__ из класса pythonically inheriting

import numpy as np 

class Parray(np.ndarray): 
    def __new__(self, p = Parameters(), dimensionality = 2): 

     print "Initializing Parray with initial dimensionality %s..." % dimensionality 

     self.p = p # store the parameters 

     if dimensionality == 2: 
      shape = (p.nx, p.ny) 
      self.pshape = shape 
     elif dimensionality == 3: 
      shape=(p.nx, p.ny, p.nx) 
      self.pshape = shape 
     else: 
      raise NotImplementedError, "dimensionality must be 2 or 3" 

     # ...Set other variables (ellided) 

     subarr = np.ndarray.__new__(self, shape, dtype, buffer, offset, strides, order) 
     subarr[::] = np.zeros(self.pshape) # initialize to zero 
     return subarr 
... 

class SirPlotsAlot(Parray): 
    def __init__(self, p = Parameters(), dimensions = 3): 
     super(SirPlotsAlot, self).__new__(p, dimensions)  # (1) 

объектов в моей программе доля наборов параметров путем передачи объекта р = Параметры () назад и вперед.

Теперь, когда я печатаю (файл auxiliary.py):

import auxiliary 
from parameters import Parameters 
p = Parameters() 
s = auxiliary.SirPlotsAlot(p, 3) 

ожидал получить хороший "Инициализация PArray с начальной размерностью 3", я получаю "2", вместо этого. НО если я типа:

import auxiliary 
s = auxiliary.SirPlotsAlot() 

я

---> 67    shape = (p.nx, p.ny) 
"AttributeError: 'int' object has no attribute 'nx'" 

Он считает, что "р" является ИНТ, что это не так. Я могу получить много странных, казалось бы, несвязанных ошибок, если я буду играть с ним. Он считает, что это «2». Я полностью потерян.

Я пробовал с и без комментария # (1) (супер-вызов).

Другие ошибки от игры вокруг включают «AttributeError:„список“объект не имеет атрибута„р“», «TypeError: новый() принимает ровно 2 аргумента (1 дано)», «ValueError: нужно больше, чем 0 значения для распаковки "(я заменил аргументы аргументами * args, что я не очень хорошо понимаю).

+1

Если Python считает, что 'p' является int, это, вероятно, правильно. Используйте 'pdb', чтобы поставить точку останова на эту строку и посмотреть, что у вас есть. Сделайте трассировку стека, чтобы увидеть, как вы туда попали. Заметьте очень внимательно, если файлы, упомянутые в трассе, являются теми, которые вы * думаете * должны быть там. Более одного человека перепутались, когда пути библиотеки были немного неправильными. –

+3

Одна проблема, которая подсказывает, что в вашем коде может быть проблема, заключается в том, что вызов «p = Parameters()» в '__init__', вероятно, не делает то, что вы думаете. Он не создает новый экземпляр Parameters всякий раз, когда вызывается «Parray .__ new__»: вместо этого он делает * one *, когда функция сначала объявляется. IOW, каждый Parray разделяет экземпляр параметра, когда он не передается, что вряд ли было вашим намерением. [Я не понимаю, как это может быть проблемой здесь, но это может вызвать проблемы в другом месте.] – DSM

+4

Ваше совместное использование '__new __()' и '__init __()' является ... неортодоксальным, мягко говоря. Почему вы снова используете '__new __()' в своем классе Parray? Это похоже на простой старый метод '__init __()' для меня; нет смысла писать его как '__new __()'. И почему вы храните атрибуты в классе? (В '__new __()' первый параметр является ссылкой на класс, а не на экземпляр, потому что нет экземпляра.) – kindall

ответ

1

Я собираюсь эхо добровольно и говорю «не используйте __new__». Ваш метод Parray.__new__ больше похож на инициализацию, и он должен использовать __init__, как и подкласс.

+0

Вы уверены? Я думаю, что подклассификация 'np.ndarray', вы должны использовать' __new__', а не '__init__' http://docs.scipy.org/doc/numpy/user/basics.subclassing.html – keflavich

+0

Это было именно то, что я думал. Вот почему я надеялся, что каждый подкласс моего нового подкласса ndarray не должен будет следовать правилам ndarray. Один из способов исследования, который я сейчас рассматриваю, - это попробовать обработать Parray как ndarray. В качестве быстрого исправления я удалил переменные по умолчанию в инициализации класса и сделал вспомогательные функции: NewSirPlotsAlot (p = Parameters() dimensions = 3): return SirPlotsAlot (p, размеры). Не совсем то, что я хочу, но, похоже, это работает. – Erasmus

+0

@keflavich: Хорошая точка. Я не видел много кода python, который требует '__new__'. То, что вы, вероятно, не хотите делать, это вызвать '__new__' из' __init__', поскольку он уже будет вызван. –

 Смежные вопросы

  • Нет связанных вопросов^_^