Шаг 149.
Python: сборник рецептов.
Классы и объекты. Вызов метода объекта с передачей имени метода в строке

    На этом шаге мы рассмотрим использование getattr() и operator.methodcaller().

Задача

    У вас есть имя метода, хранящееся в виде строки, и вы хотите вызывать этот метод.

Решение

    В простых случаях вы можете использовать getattr():

>>> import math
>>> class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return 'Point({!r:},{!r:})'.format(self.x, self.y)

    def distance(self, x, y):
        return math.hypot(self.x - x, self.y - y)

>>> p = Point(2, 3)
>>> d = getattr(p, 'distance')(0, 0) # Вызов p.distance(0, 0)
>>> 

    Альтернативный подход - использование operator.methodcaller(). Например:

>>> import operator
>>> operator.methodcaller('distance', 0, 0)(p)
3.6055512754639896
>>>

    operator.methodcaller() может оказаться полезным, если вы хотите искать метод по имени и раз за разом предоставлять одни и те же аргументы. Например, если вам нужно отсортировать целый список точек:

>>> points = [
    Point(1, 2),
    Point(3, 0),
    Point(10, -3),
    Point(-5, -7),
    Point(-1, 8),
    Point(3, 2)
]

>>> # Сортируем по расстоянию от (0, 0)
>>> points.sort(key=operator.methodcaller('distance', 0, 0))
>>> for p in points:
    print(p)

    
Point(1,2)
Point(3,0)
Point(3,2)
Point(-1,8)
Point(-5,-7)
Point(10,-3)
>>>


Обсуждение

    Вызов метода на самом деле состоит из двух отдельных шагов: поиска атрибута и вызова функции. Чтобы вызвать метод, вы просто ищете атрибут, используя getattr(), как и для любого другого атрибута. Чтобы вызывать результат как метод, просто обращайтесь с результатом поиска как с функцией.

    operator.methodcaller() создает вызываемый объект, а также фиксирует аргументы, которые будут предоставлены методу. Вам остается только предоставить подходящий аргумент self. Например:

>>> p = Point(3, 4)
>>> d = operator.methodcaller('distance', 0, 0)
>>> d(p)
5.0
>>> 

    Вызов методов с использованием имен, содержащихся в строках, является обычным в коде, который эмулирует объявления условий, или вариантах паттерна (шаблона проектирования) "Посетитель". См. следующий рецепт, где приведен более продвинутый пример.

    На следующем шаге мы рассмотрим реализацию шаблона проектирования "Посетитель".




Предыдущий шаг Содержание Следующий шаг