вещи, которые я не могу получить python. ограниченный метод, действующий как инопланетянин - PullRequest
0 голосов
/ 29 мая 2020

Я не понимаю это поведение, я изменил 'r' в классе 'f', и он отражается обратно на 'q', как вы можете видеть, 'qr' указывает, что теперь он ссылается на 'лямбда-функцию', но в то же время адрес всегда '0x037591F0', так почему 'qr ()' не работает?

class f:
    def r(self):
        print('bla bla bla')

>>> q=f()
>>> f.r
<function f.r at 0x0378F4B0>
>>> q.r
<bound method f.r of <__main__.f object at 0x037591F0>>
>>> f.r=lambda : 'google'
>>> f.r
<function <lambda> at 0x015F9348>
>>> q.r
<bound method <lambda> of <__main__.f object at 0x037591F0>>
>>> q.r()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() takes 0 positional arguments but 1 was given

Ответы [ 3 ]

1 голос
/ 29 мая 2020

r - это атрибут класса, значением которого является функция. Когда вы обращаетесь к нему из экземпляра класса, вы фактически не получаете обратно объект function: вы возвращаете результат метода функции __get__, который является новым method объект. Кроме того, каждый такой доступ создает объект новый method, но поскольку этот объект недолговечен (в основном, он существует достаточно долго, чтобы его можно было вызвать, затем он собирает мусор), каждый новый объект может используйте ту же память, что и предыдущий.

0 голосов
/ 29 мая 2020

В вашем случае r даже не начинается как метод stati c, но даже если это так, когда вы назначаете лямбду для r в классе, вы заменяете его, и он больше не будет методом stati c. Итак, когда его вызывает Python, он передаст self в качестве первого параметра.

import inspect


class C:
    @staticmethod
    def r():
        return 'x'


print(isinstance(inspect.getmro(C)[0].__dict__['r'], staticmethod))
C.r = lambda: 'y'
print(isinstance(inspect.getmro(C)[0].__dict__['r'], staticmethod))

Результат:

True
False
0 голосов
/ 29 мая 2020

Сначала вам нужно понять, что такое метод экземпляра и как он работает, помните, что в Python методы экземпляра живут в классе, а не в объекте, по этой причине Python передают параметр self неявным образом в каждом экземпляре метод (чтобы узнать, какой объект вызывает метод).

В вашем примере лямбда-функция не получает никаких параметров, и вы не используете параметр self, так что это говорит нам, что метод должен быть методом c stati (несвязанный метод), а не методом экземпляра (ограниченный метод), другими словами, метод "r" должен быть привязан к классу, а не к объекту. методы.

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