Что такое привязка функции в python? - PullRequest
2 голосов
/ 20 марта 2020

Я пытался понять библиотеку kivy в python. Ниже приведен полный код.

import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button

class MyGrid(GridLayout):
    def __init__(self, **kwargs):
        super(MyGrid, self).__init__(**kwargs)
        self.cols = 1

        self.inside = GridLayout()
        self.inside.cols = 2

        self.inside.name = TextInput(multiline=False)
        self.inside.add_widget(self.inside.name)
        self.inside.add_widget(Label(text="Name: "))

        self.inside.name = TextInput(multiline=False)
        self.inside.add_widget(self.inside.name)
        self.inside.add_widget(Label(text="Email: "))

        self.inside.name = TextInput(multiline=False)
        self.inside.add_widget(self.inside.name)
        self.inside.add_widget(Label(text="Phno: "))

        self.add_widget(self.inside)

        self.submit = Button(text="Submit", font_size=40)
        self.submit.bind(on_press=self.pressed)
        self.add_widget(self.submit)        

    def pressed(self, instance):
        print("pressed")



class MyApp(App):
    def build(self):
        return MyGrid()


if __name__ == "__main__":
    MyApp().run()

Здесь, в классе MyGrid, при методе init, когда я пытаюсь связать кнопку отправки (self.submit.bind) с методом pressed, аргумент с on_press не включает скобки.

self.submit.bind(on_press=self.pressed)

Почему это работает? Это потому, что это python соглашение о том, чтобы не включать скобки при передаче его методу?

А в чем смысл использования аргумента экземпляра в нажатом методе?

Ответы [ 4 ]

5 голосов
/ 20 марта 2020

Если вы передаете функцию без скобок, вы передаете сам объект функции

self.submit.bind(on_press=self.pressed)

Это обычно используется для механизмов обратного вызова, среди прочего. Если вы добавите круглые скобки, self.pressed() будет вызываться немедленно в этом же операторе вместо on_press, сохраняя эту функцию для последующего вызова в ответ на нажатие кнопки.

0 голосов
/ 20 марта 2020

Это помогает увидеть, что на самом деле оценивает self.pressed.

Экземпляр self не имеет атрибута с именем pressed. Его класс, MyGrid, имеет function -значный атрибут с тем же именем.

Таким образом, self.pressed оценивается как MyGrid.pressed. Но поскольку класс function реализует протокол дескриптора, вы не получите ссылку на этот объект function. Вместо этого вы получите результат MyGrid.pressed.__get__(self, MyGrid). И , что возвращает вызываемый объект типа method. Этот объект при вызове будет принимать любые аргументы, которые он получит, и сразу же передаст self, а эти аргументы вызову MyGrid.pressed.

Короче говоря, значение self.pressed очень похоже на функцию которые могли быть определены как

def bound_method(*args, **kwargs):
    return MyGrid.pressed(self, *args, **kwargs)

self.pressed == MyGrid.pressed
             == MyGrid.__dict__['pressed'].__get__(self, MyGrid)

и когда в конечном итоге вызывается self.pressed,

self.pressed(ins) == MyGrid.__dict_['pressed'].__get(self, MyGrid)(self, ins)
0 голосов
/ 20 марта 2020

Скобки вызов метода. В тех случаях, когда вы их опускаете, вы передаете сам метод как обратный вызов для вызова позже . Когда метод вызывается, скобки включаются, но не до тех пор.

0 голосов
/ 20 марта 2020

Python - это объектно-ориентированный язык в том смысле, что все является объектом (даже методами). В приведенном выше примере метод bind принимает вызываемый объект в качестве параметра (то есть другой метод).

Чтобы получить вызываемый объект вместо вызова метода, вы опускаете скобки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...