2012-05-15 46 views
4

我一直在寻找这样做的最佳方式,但我没有真正发现任何完全有说服力的东西。Python中的函数多态性

我正在编写一个系统,您拥有User对象和一个管理这些用户的集合。每个用户都有一个名称,我想在管理器中指定一个可以取用户名或用户对象本身名称的函数。

class UserManager: 
    def remove_user(self,user_or_username): 
    #If user_or_username is a string 
    remote.remove(user_or_username) 
    #If user_or_username is a User object 
    remote.remove(user_or_username.name) 

有没有这样做的好办法,或者是isinstance的使用方式去?

+0

是的,'isinstance'应该没问题。 –

+0

只有当您不知道您是否有名称或用户对象时,多态才真正起作用。大多数情况并非如此。除非你真的需要,否则你应该抵制超载函数的诱惑。在这里你有一个方法,当给出一个字符串只是链接到另一个方法。这是一种代码味道:你应该直接调用另一种方法;当你有一个用户名直接调用'manager.remove(username)'。 – Duncan

+0

您的观点是有效的@邓肯,但在这种情况下,经理是一个中间层,其工作是为我的应用程序的用户进行适当的调用。我想探索这个选项,以知道我在处理时有多大的灵活性! – Parham

回答

5

mgilson's一种解决方案,但略有不同:

def remove_user(self,user_or_username): 
    try: 
     #If user_or_username is a User object 
     username = user_or_username.name 
    except AttributeError: #Oops -- didn't works. ask forgiveness ;-) 
     #If user_or_username is a string 
     username = user_or_username 
    remote.remove(username) 

为什么?因为这样,remove()中的AttributeError s不被抑制。

这可能是无关紧要的,但我更喜欢把异常处理集中到我真正想要拥有它们的地方。

+0

为了更好的分解,您可以考虑为try/except块提取一个函数。这在其他地方也可能有用。 –

+1

@KarlKnechtel那么,一个'username = getattr(user_or_username,'name',user_or_username)'也是一种可行的方法... – glglgl

+0

异常处理集中的好处。 – mgilson

2

有时蟒蛇人喜欢说“这是更好地请求原谅比许可” ......

def remove_user(self,user_or_username): 
    try: 
     #If user_or_username is a User object 
     remote.remove(user_or_username.name) 
    except AttributeError: #Oops -- didn't works. ask forgiveness ;-) 
     #If user_or_username is a string 
     remote.remove(user_or_username) 

但我说这只是喜好的问题真的。如果您知道只会获取字符串或User实例,则还可以使用isinstance

2

我会用isinstance,但是这也适用:

def remove_user(self, user): 
    if hasattr(user, "name"): 
     self.remove(user.name) 
    else: 
     self.remove(user) 
3

使用isinstance是一个好办法...有这个解决方案多一个途径

if hasattr(user_or_username, 'name'): 
    # this object has <name> attribute 
    remote.remove(user_or_username.name) 
else: 
    remote.remove(user_or_username)