Pythonic способ обработки метода в структуре данных сети - PullRequest
4 голосов
/ 27 октября 2011

Итак, еще один вопрос о том, что такое Pythonic! В данном случае прикладной областью являются сетевые алгоритмы (например, узлы, ребра, Dijkstra, что-то в этом роде ...), то, что я только ранее кодировал на строго типизированных языках, где мы можем быть совершенно уверены, что все .

Тем временем в Python у меня есть класс Net; один экземпляр этого класса представляет сеть. У меня есть класс Edge, который создается для каждого ребра в сети. Каждый экземпляр Edge имеет, помимо прочего, уникальный id.

Иногда я хочу удалить ребро, ссылаясь на соответствующий экземпляр Edge. В других случаях я хочу удалить Edge, используя id. Если честно, я начинаю забывать, какие переменные Edges, а какие ids. Я думаю, что я предпочел C ++ для этой работы: -P

Поэтому я предлагаю два решения:

  1. Начните использовать системы Венгерская нотация - лучше назовите мои переменные, чтобы я знал, являются ли они действительными объектами Edge или просто идентификатором Edge, который я хочу. Реализуйте строгую типизацию - make remove_edge (который является методом Net) явно отклоняет все, что не является Edge. Создайте функцию-оболочку remove_edge_id, которая ищет соответствующий Edge из ее id и затем вызывает remove_edge; эта функция также отклоняет все, что не является id.

  2. Используйте утку. Пусть remove_edge проверит, является ли аргумент id или Edge, и просто сделайте с ним правильную вещь.

Какое время считаешь?

Ответы [ 3 ]

4 голосов
/ 27 октября 2011

Решение по типизации уток гораздо более питонское.Однако вместо того, чтобы проверять аргумент, чтобы определить, является ли он идентификатором или ребром, просто обработайте его так, как если бы это был более распространенный случай, а если это не сработает, попробуйте другой способ.

Если вы используете явную проверку типов, которая иногда является единственным способом, используйте isintance() вместо type(), чтобы она работала с подклассами.

Переменная может быть с хорошим или плохим именем, который является ортогональным к тому, используете ли вы строгую типизацию или нет.Если у вас есть некоторые переменные, которые ссылаются на Edge ID, и другие, которые ссылаются на экземпляр Edge, то их различение каким-то образом кажется разумным, даже если вы используете утку.Я бы использовал что-то вроде edge и edge_id, а не венгерский.

2 голосов
/ 27 октября 2011

Я бы сказал, смесь обоих.

Хорошей практикой является иметь имена объектов, которые вы можете сказать, что они есть или что они могут сделать, посмотрев на них (по большей части). Я бы назвал мои ребра edge и мои ребра edge_id.

Я бы, вероятно, использовал твою идею набирания утки для remove_edge.

def remove_edge(edge):
    if isinstance(edge, int):
        edge = get_edge_from_id(edge)
    #delete edge here!!
1 голос
/ 27 октября 2011

Если вы знаете, как удалить свой край по идентификатору, вы можете просто сделать что-то вроде этого:

class Net:
   def remove_edge(self, edge):
      try:
         self.remove_edge_by_id(edge.id)
      except AttributeError:     # oups, edge was not an Edge, it has no id
         self.remove_edge_by_id(edge)   # it should be an id
...