4

所以,关于什么是 Pythonic 的另一个问题!在这种情况下,应用程序领域是网络算法(如节点、边、Dijkstra 之类的东西......),我以前只用强类型语言编码过,我们可以非常确定一切都是什么。

同时在 Python 中,我有一个类Net;此类的单个实例代表一个网络。我有一个Edge为网络中的每个边缘实例化的类。Edge除其他外,每个实例都有一个唯一的id.

有时我希望通过引用相关Edge实例来删除边缘。其他时候我希望使用它的id. 老实说,我开始忘记哪些变量是Edges,哪些是ids. 我想我更喜欢 C++ 来完成这项工作:-P

所以我提出两个解决方案:

  1. 开始使用系统匈牙利符号 - 更好地命名我的变量,以便我知道它们是实际的 Edge 对象还是只是我想要的 Edge 的 id。实现强类型——make remove_edge(这是一个方法Net)明确拒绝任何不是Edge. 制作一个包装函数remove_edge_id,从中查找相关内容Edgeid然后调用remove_edge; 这个函数同样拒绝任何不是id.

  2. 使用鸭子打字。remove_edge检查参数是 anid还是 an并用它做Edge正确的事情。

你猜怎么着?

4

3 回答 3

4

鸭子类型的解决方案是 Pythonic 的。但是,与其测试参数以查看它是 ID 还是边缘,不如先将其视为更常见的情况,如果这不起作用,请尝试另一种方式。

如果您确实使用显式类型检查(有时这是唯一的方法),请使用isintance()而不是type()这样,它将与子类一起使用。

变量可以命名好或命名不佳,这与您是否使用强类型无关。如果您有一些引用 Edge ID 的变量,以及其他引用 Edge 实例的变量,那么即使您使用鸭子类型,以某种方式区分它们似乎也很聪明。我会使用类似edgeedge_id不是匈牙利语的东西。

于 2011-10-27T16:44:47.550 回答
2

我会说两者兼而有之。

拥有对象的名称是一种很好的做法,您可以通过查看它们来判断它们是什么或它们可能会做什么(大部分情况下)。我会命名我的边缘edge和边缘 ids edge_id

我可能会使用你的鸭子打字想法remove_edge

def remove_edge(edge):
    if isinstance(edge, int):
        edge = get_edge_from_id(edge)
    #delete edge here!!
于 2011-10-27T16:46:32.553 回答
1

如果您知道如何通过 id 删除边缘,则可以简单地执行以下操作:

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
于 2011-10-27T16:52:07.407 回答