Рассмотрим этот пример шаблона стратегии в Python (адаптирован из примера здесь ).В этом случае альтернативной стратегией является функция.
class StrategyExample(object):
def __init__(self, strategy=None) :
if strategy:
self.execute = strategy
def execute(*args):
# I know that the first argument for a method
# must be 'self'. This is just for the sake of
# demonstration
print locals()
#alternate strategy is a function
def alt_strategy(*args):
print locals()
Вот результаты для стратегии по умолчанию.
>>> s0 = StrategyExample()
>>> print s0
<__main__.StrategyExample object at 0x100460d90>
>>> s0.execute()
{'args': (<__main__.StrategyExample object at 0x100460d90>,)}
В приведенном выше примере s0.execute
является методом (непростая ванильная функция) и, следовательно, первый аргумент в args
, как и ожидалось, равен self
.
Вот результаты для альтернативной стратегии.
>>> s1 = StrategyExample(alt_strategy)
>>> s1.execute()
{'args': ()}
В этом случае s1.execute
является простой ванильной функцией и, как и ожидалось, не получает self
.Следовательно args
пусто.Подождите минуту!Как это случилось?
И метод, и функция были вызваны одинаково.Как метод автоматически получает self
в качестве первого аргумента?И когда метод заменяется простой ванильной функцией, как он не получает self
в качестве первого аргумента?
Единственное отличие, которое я смог найти, было при проверке атрибутов стратегии по умолчанию и альтернативной стратегии.
>>> print dir(s0.execute)
['__cmp__', '__func__', '__self__', ...]
>>> print dir(s1.execute)
# does not have __self__ attribute
Имеет ли атрибут __self__
значение s0.execute
(метод), но отсутствие его на s1.execute
(функция) как-то объяснить эту разницу в поведении?Как это все работает внутри?