2016-04-03 107 views
0

我有一些图形处理功能。它定义了一个类Edge和my_graph_algo:实例的重命名/别名方法名称(使用Python)

class Edge: 
    def connectsNodes(self, n1, n2): 
     .... 

def my_graph_algo(edge, more args): 
    ... 
    x = edge.connectsNodes(...) 
    ... 

e = Edge() 
my_graph_algo(e) 

到目前为止,没有什么特别的。

现在让我们想到一个Friendship的和Road的:

class Friendship: 
    def areFriends(self, f1, f2): 
     ... 

class Road: 
    def connectsTowns(self, t1, t2): 
     ... 

这些表现出相同的行为作为图形边缘:他们连接两件事情。所以我们可以使用my_graph_algo(...)作为参数FriendshipRoad。不幸的是,它们与my_graph_algo(...)不兼容,因为它们不提供connectsNodes,但它们在语义上提供相同的areFriendsconnectsTowns

所以我想以某种方式重命名动态/别名在函数调用这些功能,是这样的:

f = Friendship() 
my_graph_algo(f see areFriends as connectsNodes) # here 

r = Road() 
my_graph_algo(r see connectsTowns as connectsNodes) # and here 

我知道,能在这种情况下可以使用一些技术,但它们不正是我“M询问:

  1. 定义FriendshipRoad作为Edge亚型,提供了一个功能connectsNodes。如果你不能或不想改变这些课程,那就很糟糕。
  2. 创建适配器类,其适配FriendshipRoadEdge。单调乏味,如果你想在各种情况下使用这种“别名”技术。
  3. 在函数调用时定义一个“重定向”到相应方法的lambda函数。将需要更改my_graph_algo(...)

是否有解决方案,不需要修改现有的类/函数,也不需要引入额外的类?一些可以提供重命名/别名权的地方。

此外:如果参数edge实际上是表示边的对象列表,它将会如何显示。

这个问题既实用又有点学术性。

+0

你想要的包装 –

+0

我不这么认为。我解释了为什么我想避免使用适配器/包装器模式,并且我也没有看到使用@的Python包装技术在这里可以如何帮助。也许2分钟不足以完全理解我的帖子? ;-) – Michael

+1

带有@的东西被称为装饰器,而不是包装器。如果你没有使用包装器,那么答案是:不,Python不提供任何内置/标准函数/语法来执行你想要的操作 –

回答

0

您可以将类似Friendship.connectsNodes = Friendship.areFriends的别名添加到课程中,但只能在本地使用。如果从其他文件导入它不会影响类。

对于您的示例代码:

class Edge: 
    def connectsNodes(self, n1, n2): 
     return n1+n2 

def my_graph_algo(edge): 
    n1, n2 = 2, 5 
    x = edge.connectsNodes(n1, n2) 
    return x 

e = Edge() 
print(my_graph_algo(e)) 

class Friendship: 
    def areFriends(self, f1, f2): 
     return f1-f2 

class Road: 
    def connectsTowns(self, t1, t2): 
     return t1*t2 


Friendship.connectsNodes = Friendship.areFriends 
f = Friendship() 
print(my_graph_algo(f)) 

Road.connectsNodes = Road.connectsTowns 
r = Road() 
print(my_graph_algo(r))