2013-11-25 3 views
0

Это немного уникальный запрос. Я ищу, чтобы увидеть, если это возможно добавить дополнительные функции к списка() данные структурированным, как «добавить» Я хотел бы добавить поворот координат под новым именем класса, который наследует свойства списка:Python: добавить новые функции в структуру списка под другим именем

class __VecRot(list): 

    def __init__(self, coords): 
     self.coords = coords 
     print coords   

    def double(self): 
     self.coords = [i*2 for i in self.coords] 

a = __VecRot([1,0,0]) 

Эта строка кода инициализирует координаты, но не определяет «a» как список со значениями в [1,0,0]. Таким образом, когда этот код выполняется.

В настоящее время

print a 

>>> a 
[] 

Ищу

print a 

>>> a 
[1,0,0] 

и дополнительные функции, такие, что справедливо следующее:

a.double() 
print a 
>>> a 
[2,0,0] 

Можно ли определить класс значение? чтобы он мог переносить существующую структуру данных?

+0

Рассмотрим подклассов 'UserList' вместо' list' непосредственно. – aragaer

ответ

5

Вы дублируете фактический контейнер. Если вы получаете от list, у вас уже есть хранилище. Рассмотрим это:

class __VecRot(list): 

    def __init__(self, coords): 
     list.__init__(self, coords) 

    def double(self): 
     for i in range(len(self)): 
      self[i] = self[i] * 2 

a = __VecRot([1,0,0]) 

a.double() 

print a 

Или, если у вас есть coords поле в любом случае, вам не нужно извлекать из list:

class __VecRot: 

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

    def double(self): 
     self.coords = [i*2 for i in self.coords] 

    def __len__(self): 
     return len(self.coords) 

    def __str__(self): 
     return "__VecRot["+str(self.coords)+"]" 

    def __repr__(self): 
     return "__VecRot("+repr(self.coords)+")" 

a = __VecRot([1,0,0]) 

a.double() 

print a 

который, кажется, лучше практики. Вы также должны перегружать другие методы интерфейса списка (например, __getitem__). Из-за duck typing в Python не имеет значения, имеет ли ваш класс list, если он содержит все необходимые методы.

+0

Спасибо, я думаю, я это понимаю. Теперь я должен понять, почему он работает с простой функцией, но не с большой функцией, включая операции с Numpy. – CromeX

+0

Ahh ... отлично теперь я понимаю, что вы подразумеваете под дублированием контейнера. Используя 'self = blah blah', я переопределяю' self', поэтому он игнорируется в вызове. Когда я сохраняю на 'self [:] = blah blah', я вижу, что он хранит один и тот же контейнер. Спасибо – CromeX

+0

@CromeX Да, точно. Нет проблем! – BartoszKP

0

Можно наследовать от класса list, чтобы создать свои собственные пользовательские функции в пределах области list. Ты делаешь это неправильно.

Это гораздо проще, чем вы думаете:

class __VecRot(list): 

    def double(self): 
     self[:] = [i*2 for i in self[:]] 

Затем вы можете использовать его как это:

>>> a = __VecRot([1,0,0]) 
>>> a 
[1, 0, 0] 
>>> a.double() 
>>> a 
[2, 0, 0] 
>>> a.double() 
>>> a 
[4, 0, 0] 
Смежные вопросы