那么,关于什么是Pythonic的另一个问题!在这种情况下,应用程序域是网络算法(如节点,边缘,Dijkstra,那种东西......),我以前只用强类型语言编写的东西,我们可以非常确定是什么
同时在Python中,我有一个班级Net
;此类的单个实例表示网络。我有一个类Edge
,它为网络中的每个边缘实例化。除其他事项外,每个Edge
实例都有一个唯一的id
。
有时我希望通过引用相关的Edge
实例来删除边缘。其他时候我希望使用id
删除Edge。说实话,我开始忘记哪些变量是Edges
,哪些是ids
。我认为我更喜欢C ++来完成这项工作:-P
所以我提出两个解决方案:
开始使用系统匈牙利表示法 - 更好地命名我的变量,以便我知道它们是实际的Edge对象还是我想要的Edge的id。实施强类型 - 使remove_edge
(这是Net
上的方法)明确拒绝任何非Edge
的内容。创建一个包装函数remove_edge_id
,从Edge
中查找相关的id
,然后调用remove_edge
;此功能同样拒绝任何不是id
。
使用duck typing。让remove_edge
检查参数是id
还是Edge
,然后用它做正确的事。
Whadday'所有人都认为?
答案 0 :(得分:4)
鸭子打字解决方案远远超过Pythonic。然而,不是测试参数以查看它是ID还是边缘,而是将其视为首先是更常见的情况,如果这不起作用,请尝试另一种方式。
如果您确实使用显式类型检查(有时是唯一的方法),请使用isintance()
而不是type()
,以便它可以用于子类。
变量可以是命名良好或命名不佳的,这与您是否使用强类型是正交的。如果您有一些引用Edge ID的变量,以及引用Edge实例的其他变量,那么即使您正在使用duck typing,以某种方式区分它们也会很明智。我会使用edge
和edge_id
而不是匈牙利语。
答案 1 :(得分:2)
我想说两者兼而有之。
优良作法是拥有对象的名称,通过查看它们可以分辨它们是什么或者它们可以做什么(大多数情况下)。我会将边缘edge
和边缘ID edge_id
命名为。
我可能会对remove_edge
使用你的鸭子打字理念。
def remove_edge(edge):
if isinstance(edge, int):
edge = get_edge_from_id(edge)
#delete edge here!!
答案 2 :(得分: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