我正在从Java背景学习Python(3.x)。
我有一个python程序,我在其中创建一个personObject并将其添加到列表中。
p = Person("John")
list.addPerson(p)
但是为了灵活性,我还希望能够直接在addPerson方法中声明它,如下所示:
list.addPerson("John")
addPerson方法将能够区分我是否发送Person-object或String。
在Java中,我将创建两个单独的方法,如下所示:
void addPerson(Person p) {
//Add person to list
}
void addPerson(String personName) {
//Create Person object
//Add person to list
}
我无法在Python中找到如何执行此操作。我知道一个type()函数,我可以用它来检查参数是String还是Object。然而,这对我来说似乎很混乱。还有另一种方法吗?
编辑:
我想替代解决方法就是这样(python):
def addPerson(self, person):
//check if person is string
//Create person object
//Check that person is a Person instance
//Do nothing
//Add person to list
但与Java中的重载解决方案相比,它看起来很混乱。
答案 0 :(得分:6)
使用@Kevin指向的引用,您可以执行以下操作:
from multimethod import multimethod
class Person(object):
def __init__(self, myname):
self.name = myname
def __str__(self):
return self.name
def __repr__(self):
return self.__str__()
@multimethod(list, object)
def addPerson(l, p):
l = l +[p]
return l
@multimethod(list, str)
def addPerson(l, name):
p = Person(name)
l = l +[p]
return l
alist = []
alist = addPerson(alist, Person("foo"))
alist = addPerson(alist, "bar")
print(alist)
结果将是:
$ python test.py
[foo, bar]
(您需要先安装multimethod)
答案 1 :(得分:1)
我用来实现这种特定模式的一种常见方式是:
def first(self, person):
try:
person = Person(person)
except ConstructionError as e:
pass
# do your thing
我不知道这是否适合你。如果您使用现有Person
调用它,您希望捕获此处生成的任何错误Person
。如果它像person_factory
那样可能会更好,因为它可以返回现有对象,如果它已经是一个人而不是抛出异常。
Multimethods在Python中有所不同; Python允许您实现几乎任何类型的语义接口,但代价是在某个地方进行额外的工作,并且您通常可以在“某处”移动,以便最好地将其隐藏起来。
另外......这有点优点......你有时会在C ++ / C#/ Java中看到这样的东西:
int sum(int a, int b) {
return (a+b)
}
float sum (float a, float b) {
return (a+b)
}
etc.
只需就可以在python中替换
def sum(a,b):
return a+b
(虽然C ++和C#现在有auto
可以处理这样的事情,afaik)。