Я на самом деле никогда не слышал фразы «Голливудский принцип» раньше, и я не знаком с Twisted (хотя я чувствую, что должен быть). Но концепция инверсии управления не так сложна. Я думаю, что программирование GUI - хороший способ представить это. Рассмотрим следующее из здесь (слегка изменено).
import Tkinter
class App(object):
def __init__(self, master):
frame = Tkinter.Frame(master)
frame.pack()
self.button = Tkinter.Button(frame, text="QUIT", fg="red", command=frame.quit)
self.button.pack(side=Tkinter.LEFT)
self.hi_there = Tkinter.Button(frame, text="Hello", command=self.say_hi)
self.hi_there.pack(side=Tkinter.LEFT)
def say_hi(self):
print "hi there, everyone!"
root = Tkinter.Tk()
app = App(root)
root.mainloop()
Это очень простой пример инверсии управления. Он использует обратных вызовов - отсюда и голливудский принцип прозвище (спасибо Свену за ссылку). Идея в том, что вы пишете функцию, но никогда не вызываете ее. Вместо этого вы передаете его другой программе и сообщаете этой программе, когда ее вызывать. Затем вы даете контроль над этой программой. Вот подробное объяснение кода:
import Tkinter
class App(object):
Мы начнем с определения класса, который будет хранить наши обратные вызовы и передавать их соответствующим частям того, что я назову «основной программой».
def __init__(self, master):
Нашему классу нужна «магистерская программа»; главная программа - это то, что будет вызывать функции, которые мы определяем. В данном случае это корневое окно графического интерфейса. Более правильно, в контексте программирования GUI, мы можем сказать, что master
является родительским из frame
.
frame = Tkinter.Frame(master)
frame.pack()
Эти две строки создают объект Frame
, который по сути представляет собой блок, содержащий виджеты. Вы увидите, что виджет в секунду. Как видите, у него также есть родитель - тот же, что и у наших App
: master
.
self.button = Tkinter.Button(frame, text="QUIT", command=frame.quit)
self.button.pack(side=Tkinter.LEFT)
self.button
это виджет. Когда вы создаете его с помощью Tkinter.Button
, вы присваиваете ему некоторые свойства, например метку (text="QUIT"
). Вы также говорите ему, что его родитель - в данном случае, не master
, а frame
. Итак, теперь у нас есть иерархия - master -> frame -> button
. Но самое главное, что мы делаем, это: command=frame.quit
. Это говорит кнопке, что делать, когда она активируется щелчком мыши. Короче говоря, это обратный вызов. Здесь мы передаем ему метод frame
quit
, который в этом случае приводит к закрытию всей программы. Обратите внимание, что за функцией не следует ()
- это потому, что мы не хотим ее вызвать. Мы просто хотим передать его button
.
self.hi_there = Tkinter.Button(frame, text="Hello", command=self.say_hi)
self.hi_there.pack(side=Tkinter.LEFT)
Это еще один виджет, который практически идентичен первому, за исключением того, что вместо передачи self.quit
в качестве обратного вызова мы передали self.say_hi
. Поскольку это определено ниже, вы можете заменить любую функцию, которую вы хотели здесь. (В обоих приведенных выше наборах строк self.button.pack
просто указывает Button
, куда он должен идти в frame
.)
def say_hi(self):
print "hi there, everyone!"
say_hi
- это то, где вы определяете, что делает кнопка Hello
.
root = Tkinter.Tk()
app = App(root)
Теперь мы вызываем наш класс, создавая экземпляр. Мы создаем корневое окно, а затем создаем экземпляр App
с root
в качестве его родителя.
root.mainloop()
И тогда мы закончили. Мы передаем контроль Tkinter, который выполняет всю остальную работу.