2015-02-15 2 views
0

Я довольно новичок в Python, и у меня возникла проблема, для которой я не мог найти прямой ответ здесь, в stackoverflow (но я думаю, что я просто недостаточно опытен для Google правильные условия). Я надеюсь, что вы можете помочьPython - Создайте переменную класса общего класса в самом классе

Рассмотрим это:

import numpy as np 

class Data: 

    def __init__(self, data): 
     self.data = data 

    def get_dimensions(self): 
     return np.shape(self.data) 


test = Data(np.random.random((20, 15))) 
print(test.get_dimensions()) 

Это дает мне

(20, 15) 

так же, как я хотел.

Теперь вот что я хочу сделать: Во время обработки данных мне нужно будет получить форму моих наборов данных довольно часто, особенно внутри самого класса. Тем не менее, я не хочу называть NumPy каждый раз, когда я

self.get_dimensions() 

, как я думаю, что это всегда будет идти, хотя процесс анализа массива. Есть ли способ вычислить переменную формы только один раз, а затем поделиться ею внутри класса, чтобы сохранить время вычисления?

Моя проблема сложнее, так как мне нужно сначала открыть файлы, прочитать их, и из этого получить форму данных, поэтому я действительно хочу избежать этого каждый раз, когда хочу получить форму ...

Надеюсь, вы увидите мою проблему спасибо!

EDIT:

Мой вопрос уже был дан ответ, однако я хотел бы задать следить за вопрос, если это также будет эффективным:

import numpy as np 

class Data: 

    def __init__(self, data): 
     self.data = data 
     self.dimensions = self._get_dimensions() 

    def _get_dimensions(self): 
     return np.shape(self.data) 


test = Data(np.random.random((20, 15))) 
print(test.dimensions) 

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

Еще раз спасибо!

ответ

2

Конечно, вы могли бы сделать это следующим образом:

class Data: 

    def __init__(self, data): 
     self.data = data 
     self.dimensions = None 

    def get_dimensions(self): 
     self.dimensions = (np.shape(self.data) if 
      self.dimensions is None else 
      self.dimensions) 
     return self.dimensions 

Если вы когда-нибудь нужно измените self.data и пересчитайте self.dimensions, вам может быть лучше с аргументом ключевого слова, чтобы указать, хотите ли вы пересчитать результат. Пример:

def get_dimensions(self, calculate=False): 
     self.dimensions = (np.shape(self.data) 
      if calculate or self.dimensions is None 
      else self.dimensions) 
     return self.dimensions 
+0

Проблема заключается в том, вы никогда не установить размеры, так что вы всегда в конечном итоге вычисления его повторно, а затем вернуть его, вместо того, чтобы использовать ранее вычисленный результат ... –

+0

Ах, не знаю, что я мог сделай это! Наверное, я изучаю python с трудом, ха-ха. Большое спасибо! – HansSnah

+0

@mu 無 Правильно! Фиксация этого сейчас. – Eithos

2

Вы можете кэшировать результат в качестве переменной-члена (если я правильно понял вопрос):

import numpy as np 

class Data: 

    def __init__(self, data): 
     self.data = data 
     self.result = None 

    def get_dimensions(self): 
     if not self.result: 
      self.result = np.shape(self.data) 
     return self.result 


test = Data(np.random.random((20, 15))) 
print(test.get_dimensions()) 
2

Форма массива непосредственно хранится в массиве и не является вычисленным значением. Форма массива должна быть сохранена, поскольку резервная память представляет собой плоский массив. Таким образом, у (4, 4), (2, 8) и (16,) будет такой же базовый массив. Без сохранения формы массив не может выполнять операции индексирования. numpy.shape действительно полезен только для получения формы объектов типа массива (таких как списки или кортежи).

shape = self.data.shape 

Я пропустил последний бит, в котором вас беспокоили некоторые другие дорогостоящие вычисления, которые вы не указали. Лучшим решением является кэширование вычисленного значения в первый раз и возврат кешированного значения при последующих вызовах метода. Чтобы справиться с дополнительным вычислением

from random import random 

class Data: 
    @property 
    def dimensions(self): 
     # Do a try/except block as the exception will only every be thrown the first 
     # time. Secondary invocations will work quicker and not require any checking. 
     try: 
      return self._dimensions 
     except AttributeError: 
      pass 
     # some complex computation 
     self._dimensions = random() 
     return self._dimensions 

d = Data() 
assert d.dimensions == d.dimensions 
+0

Хорошо, точка взята. Итак, если бы я хотел вернуть форму только одного массива, я вижу, что нет необходимости переписывать вышеупомянутое утверждение. Тем не менее, в моей функции get_dimensions я делаю больше, чем просто возвращаю форму, поэтому я действительно хочу избежать дополнительных шагов все время – HansSnah

0

если ваш размер не меняется вы можете сделать его более простым.

import numpy as np 

class Data: 

    def __init__(self, data): 
     self.data = data 
     self.dimension=np.shape(self.data) 

    def get_dimensions(self): 
     return self.dimension 


test = Data(np.random.random((20, 15))) 
print(test.get_dimensions())