模仿方法重载算是Pythonic吗?
在Python中,模仿静态类型语言里的“方法重载”算不算是符合Python风格呢?我指的是写一个函数,检查它的参数类型,然后根据这些类型表现出不同的行为。
下面是一个例子:
class EmployeeCollection(object):
@staticmethod
def find(value):
if isinstance(value, str):
#find employee by name and return
elif isinstance(value, int):
#find employee by employee number and return
else:
raise TypeError()
5 个回答
5
不,这里的类型检查并不是很符合Python的风格。如果你不想用多个方法,另一种选择是只用一个方法,但使用多个参数:
def find(name=None, employee_number=None):
if sum(x != None for x in (name, employee_number)) != 1:
#raise exception - exactly one value should be passed in
if name is not None:
#find employee by name and return
if employee_number is not None:
#find employee by employee number and return
这样使用的时候,意图和用多个方法时一样明显:
employee1 = x.find(name="John Smith")
employee2 = x.find(employee_number=90210)
13
其实不是这样,因为这样会失去使用那些不完全相同但差不多的类型的能力。建议你创建两个不同的方法,分别叫做 find_by_name()
和 find_by_number()
。
13
这段话的意思是,使用Python的时候,有些做法并不太符合Python的风格。比如在2.6版本或者更新的版本中,如果你所有的检查都依赖于新的抽象基类(abstract base classes),那么这种做法是可以接受的,因为这些基类的设计就是为了方便这种使用。如果你发现自己在检查具体的类类型,那你就知道你的代码可能会变得脆弱,限制了它的使用。
举个例子,检查一个对象是否是numbers.Integral的实例,这样做还算可以,因为这个新的抽象基类就是为了方便这种检查而存在的。但是如果你去检查一个对象是否是int
类型,那就糟糕了,这样会排除long
、gmpy.mpz
以及其他很多类似整数的类型,完全没有必要:永远不要检查具体的类!
字符串的情况比较复杂,不过可以考虑使用basestring这个抽象类(虽然它不是新类型的抽象基类)。可能有点太严格了,但如果你在周围使用其他的抽象基类,或许在必要的时候可以勉强使用一下。绝对不要使用str
,因为这样就会排除unicode
类型,为什么要这样做呢?