Я работаю над проектом Python, который требует от меня компиляции определенных атрибутов некоторых объектов в набор данных. Код, который я сейчас использую, выглядит примерно так:
class VectorBuilder(object):
SIZE = 5
def __init__(self, player, frame_data):
self.player = player
self.fd = frame_data
def build(self):
self._vector = []
self._add(self.player)
self._add(self.fd.getSomeData())
self._add(self.fd.getSomeOtherData())
char = self.fd.getCharacter()
self._add(char.getCharacterData())
self._add(char.getMoreCharacterData())
assert len(self._vector) == self.SIZE
return self._vector
def _add(self, element):
self._vector.append(element)
Однако этот код немного нечист, поскольку добавление / удаление атрибутов в / из набора данных также требует правильной настройки переменной SIZE
. Причина, по которой у меня даже есть переменная SIZE
, заключается в том, что размер набора данных должен быть известен во время выполнения до создания самого набора данных.
Я подумал о том, чтобы вместо этого сохранить список всех функций, использованных для построения набора данных в виде строк (как в attributes = ['getPlayer', 'fd.getSomeData', ...]
), а затем определить функцию build
как что-то вроде:
def build(self):
self._vector = []
for att in attributes:
self._vector.append(getattr(self, att)())
return self._vector
Это позволило бы мне получить доступ к размеру просто как len(attributes)
, и мне нужно всего лишь отредактировать attributes
, но я не знаю, как заставить этот подход работать с связанными вызовами функций, такими как self.fd.getCharacter().getCharacterData()
.
Есть ли более чистый способ выполнить то, что я пытаюсь сделать?
EDIT:
Требуется дополнительная информация и пояснения.
- Я использовал
__
из-за какого-то дурного совета, который я прочитал в Интернете (по сути, я сказал, что я должен использовать _
для членов, закрытых для модуля, и __
для членов класса, закрытых). Я отредактировал их для _
атрибутов.
- Геттеры являются частью фреймворка, который я использую.
- Вектор хранится как закрытый член класса, поэтому мне не нужно передавать его методам конструирования, которые на самом деле более многочисленны, чем простой
_add
, делая некоторые другие вещи, такие как нормализация и bool->int
преобразование на элементы перед добавлением их в вектор.
SIZE
в том виде, в каком оно существует в данный момент, является истинной константой. Ему дается только значение в первой строке VectorBuilder
, и оно никогда не изменяется во время выполнения. Я понимаю, что не разъяснил это должным образом в основном посте, но новые атрибуты никогда не добавляются во время выполнения. Корректировка, о которой я говорил, будет происходить во время программирования. Например, если бы я хотел добавить новый атрибут, мне нужно было бы добавить его в функцию build
, например ::
self._add(self.fd.getCharacter().getAction().getActionData().getSpeed())
, а также измените определение SIZE
на SIZE = 6
.
- Атрибуты компилируются в то, что в настоящее время представляет собой простой список Python (но, вероятно, будет заменен массивом с нулями), а затем передаются в нейронную сеть в качестве входного вектора. Однако сама нейронная сеть должна быть построена в первую очередь, и это происходит до того, как какие-либо данные становятся доступными (то есть до создания любых входных векторов). Однако для успешного построения нейронной сети необходимо знать размер входных векторов, которые она будет получать. Вот почему необходим
SIZE
, а также причина утверждения assert
- чтобы удостовериться, что векторы, которые я передаю в сеть, на самом деле соответствуют размерам, которые, как я утверждал, я передаю ей.
Я знаю, что код не пифоничен, поэтому я здесь - код работает, он просто уродлив.