2012-04-19 7 views
2

Я хотел бы нанести на карту метод над списком объектов, создающих экземпляры разных классов. Все объекты наследуются от одного и того же базового класса и определяют метод требуемого имени.сопоставить метод над списком различных объектов

Для наглядности рассмотрим следующий код:

class A: 
    def __init__(self, x): 
     self.x = x 

    def foo (self): 
     return self.x 

class B(A): 
    def foo (self): 
     return self.x+1 

class C(A): 
    def foo (self): 
     return self.x-1 

Теперь рассмотрим список объектов экземпляры классов B и C. Я хотел бы сделать что-то вроде этого:

result = [] 
for obj in [B(1), C(1)]: 
    result.append(obj.foo()) 

Как вы перейдете к отображению метода foo для каждого элемента списка? Возможно ли это? Лучшее, что я мог придумать, это что-то вроде этого:

map(A.foo, [B(1), C(1)]) 

но ясно, что он не возвращает желаемого результата. Как я могу указать метод, связанный с объектом?

Надеюсь, я ясно дал понять.

NB: Я работаю в основном с Python2.7, но в равной степени интересовался бы решениями, применимыми для «новых» версий.

+0

Вы отсутствующий звонок в Форме __init__ B и C, чтобы __init__ не называемый неявно. – loki

ответ

3
>>> map(lambda x: x.foo(), [B(1), C(1)]) 
>>> [2, 0] 

Лямбда-функция будет принимать каждый объект в списке и вызывать foo() на этом объекте. Таким образом, полученный список будет иметь результаты, возвращаемые foo() соответствующего объекта.

4

Map(A.foo, [B(1), C(1)]) в основном делает A.foo(B(1)) и A.foo(C(1)) который не является тем, что вы ищете.

Используя классы сверху, я бы просто сделать:

In: objs = [B(1), C(1)] 
In: [x.foo() for x in objs] 
Out: [2, 0] 

Amjith имеет реализацию чистую карту, если вы предпочитаете что.

3

Для большинства практических целей, я бы рекомендовал @ список понимания ALG, но вы можете сделать это с map, а также:

>>> import operator 
>>> map(operator.methodcaller("foo"), [B(1), C(1)]) 
[2, 0] 
Смежные вопросы