Перезапись связанных методов в python, когда функция требует атрибута класса - PullRequest
0 голосов
/ 29 мая 2018

Скажем, у меня есть класс:

class Data():
    def __init__(self):
        self.scores = [] 
        self.encoding= {1: 'first', 2: 'second', 3:'third'}
    def build():
        self.scores = [1, 2, 3]
    def translate(self):
        return [self.encoding[score] for val in self.scores]

Теперь я хочу иметь возможность переводить столбцы для данного объекта данных ...

# I want to be able to do
d= Data()    
d.scores.translate()
# AttributeError: 'list' object has no attribute 'translate'

# Instead of
d= Data()    
d.translate()

Теперь я полностью осведомленчто я пытаюсь получить доступ к методу, который НЕ существует для этого списка (translate ()).Я хочу иметь возможность выполнять вызовы методов, как упомянуто выше (d.scores.translate ()), потому что у меня может быть некоторая конкретная часть d.scores, которую я хочу перевести.

Например, если d.scores был вложенным пустым массивом (я хочу перевести только первые 5 столбцов, но сохранить все строки)

#this is what I would like to be able to do
d.scores[:, 1:5].translate()

# And I don't want to build a kwarg in the translate method to handle it like
d.scores.translate(indices=[1])

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

Пытаюсь ли я воткнуть квадратный колышек в круглое отверстие в этой точке?Должен ли я просто сдаться и определить функцию модуля или рассмотреть kwargs?Это что-то более "питоническое"?

ОБНОВЛЕНИЕ

Я должен был сказать это раньше, но я попытался использовать маршрут kwarg и staticmethod.Я просто хочу знать, есть ли другие способы сделать это?Может быть, через подклассы?или эквивалент Python взаимодействия в Java / C # (если он существует?)

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Вы можете сделать это с помощью второго класса и использовать _scores для списка и оценки подобъекта, который манипулирует _scores:

class DataHelper(object):
   def __init__(self, data_obj):
       self.data_obj = data_obj

   def translate(self, *args):
       ... # work on self.data_obj._scores

class Data(object):
   def __init__(self):
       self.scores = DataHelper(self)
       self._scores = []

С такой структурой класса вы можете сделать это:

scores = d.scores.translate(1, 5)

И с большим количеством хитрости вы можете даже сделать:

scores = d.scores[1:5].translate()

Но для этого вам понадобится третий класс (объекты которого будут созданы временнопри индексировании объектов партитуры, чтобы d.scores [1: 5] не создавал срез списка, а новый объект с методом translate).

0 голосов
/ 29 мая 2018

Да, вы пытаетесь «протолкнуть квадратный колышек в круглое отверстие».

Ваш метод перевода работает на весь список результатов, полная остановка.Это не может быть изменено с помощью некоторых хитростей, которые просто не поддерживаются в Python.

Если вы хотите создавать сублименты, я бы рекомендовал сделать это явно.

Примеры:

# Using args/kwargs:
scores = john.translate(10, 15) # translate subslice 10:15

# Using a new static method:
scores = Person.translate_scores(john.scores[10:15])

Выглядит не так элегантно, но работает.

(Кстати: с тех пор, как вы изменили свой вопрос, у меня может быть немного занятий, но я не буду менять свой ответ при каждом вашем редактировании)

Ваша хитрость просто не работает, потому что "очки" - это не какая-то часть вашего основного класса, а просто его атрибут, который имеет свой собственный тип.Таким образом, когда вы делаете «d.scores.translate ()», translate вызывается не для d, а для списка или любого другого типа.Вы не можете изменить это, потому что это ядро ​​Python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...