До того момента, как примерно час назад, я был убежден, что в python Foo ().bar ()
является не чем иным, как короткой рукой для Foo.bar (Foo () )
, которая передает экземпляр в качестве первого параметра.В этом примере последние две строки делают (очевидно) одно и то же:
class Foo (object):
def bar (self): print "baz"
qux = Foo ()
qux.bar ()
Foo.bar (qux)
Но теперь у меня есть класс Animal, у которого есть статический метод populate (), который возвращает список всех животных, известных человеку.Также у каждого экземпляра Animal есть метод populate (), который заполняет свойства экземпляра случайными значениями.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import random
animals = [ ("Bella", "cow"), ("Spike", "dog"), ("José", "iguana"), ("Tux", "penguin") ]
class Animal (object):
@staticmethod
def populate (*args): return map (lambda x: Animal (*x), animals)
def __init__ (self, name = None, species = None):
def bar (): self.name, self.species = random.choice (animals)
self.name = name
self.species = species
self.populate = bar
def __repr__ (self): return "%s of species %s" % (self.name, self.species)
print Animal.populate ()
print Animal ("Pinky", "mouse")
qux = Animal ()
qux.populate ()
print qux
Код работает нормально, но то, что заставило меня заподозрить, было то, что print Animal.populate (qux)
вызвалстатический метод заполнения (и, следовательно, возвратил список и не заполнил плохой qux).Очевидно, мое убеждение в том, что Foo ().bar ()
была не более чем короткой рукой для Foo.bar (Foo () )
, неверно.
Это вызывает у меня различные вопросы:
- Что происходит, когда я звоню
Foo ().bar ()
? - Что происходит, когда я звоню
Foo.bar (Foo () )
? - Есть ли внутренняя разница между ними?
- Я упускаю некое фундаментальное понятие Python?
- Если бы вам пришлось написать класс, чей статический метод populate делает что-то еще, кроме метода populate, вызываемого над экземпляром этого класса, какой путь вы бы выбрали?
(Да, этодолжно быть одно и то же имя.)