2011-10-27 44 views
4

因此,关于什么是Pythonic的另一个问题!在这种情况下,应用程序域是网络算法(如在节点,边缘,Dijkstra,那种事情......),我以前只用强类型语言编码,我们可以非常确定什么是Pythonic处理网络数据结构的方法

同时在Python中,我有一个类Net;这个类的单个实例代表一个网络。我有一个类Edge,它为网络中的每个边缘实例化。除此之外,每个Edge实例都具有独特的id

有时我希望通过参考相关的Edge实例来删除边缘。其他时候,我希望使用其id删除Edge。说实话,我开始失去跟踪哪些变量是Edges,哪些是ids。我想我更喜欢C++这个工作:-P

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

  1. 开始使用系统匈牙利命名法 - 我的名字好变量,所以我知道他们是否是实际Edge对象或只是我想要的边缘的ID。实施强类型 - 使remove_edge(这是Net上的方法)明确拒绝任何不是Edge的东西。制作一个包装函数remove_edge_id,它从id中查找相关的Edge,然后调用remove_edge;此功能同样拒绝任何不是id的东西。

  2. 使用鸭子打字。请remove_edge检查参数是否为idEdge,并仅对它做正确的事情。

Whadday'all估计?

+0

这可能是值得退一步,问你为什么要同时使用对象引用发现自己和ID来跟踪边缘。它是否支持C++习惯?是否有可能修改其他的东西总是使用一个或另一个? –

+1

你指的是一个'图表',而不是'网络'。 –

+0

公平点。我被我的应用程序领域的术语蒙上了一层阴影;-) –

回答

4

鸭打字解决方案是Pythonic更加。但是,不要测试参数来查看它是ID还是边缘,只要将它看作是最常见的情况,如果不起作用,请尝试另一种方式。

如果确实使用明确的类型检查(有时是唯一的方法),请使用isintance()而不是type(),以便它能与子类一起使用。

一个变量可以是好名字或命名不清,这与您是否使用强类型是正交的。如果您有一些引用边缘ID的变量,以及其他引用Edge实例的变量,则以某种方式区分它们即使在使用鸭子打字时也很明智。尽管我使用edgeedge_id而不是匈牙利。

+0

听起来很合理,我认为这可能是确定的,但让问题持续一段时间,以鼓励讨论 –

2

我会说两者的混合。

这是一个很好的做法,可以通过查看它们(大部分)来告诉对象的名称或做什么。我会命名我的边缘edge和我的优势代码edge_id

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

def remove_edge(edge): 
    if isinstance(edge, int): 
     edge = get_edge_from_id(edge) 
    #delete edge here!! 
+0

只是我,还是会导致堆栈溢出? :-) –

+0

Woops!修好了,谢谢! – TorelTwiddler

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 
+0

+1代码说明了如何像@kindall建议的那样先处理最常见的情况。使它更清晰一点! –