Функция id (__ getattribute__) возвратила другое значение, когда метод __getattr__ определен в классе - PullRequest
0 голосов
/ 28 октября 2018

Как показано ниже, id(a.__getattribute__) возвращает другое значение, когда определен метод __getattr__.Как это случилось?(Мой Python v3.7.0)

class A():

    def __getattribute__(self,key):
        print(key)
        return super().__getattribute__(key)
    def f():
        pass
    def __getattr__(self,key):
        print(key)
        return super().__getattr__(key)


a=A()
print('id(a.__getattribute__)')
print(id(a.__getattribute__))
print(id(a.__getattribute__))
print(id(a.__getattribute__))
print(id(a.__getattribute__))

Результаты вывода:

id(a.__getattribute__)
__getattribute__
44147656
__getattribute__
12643664
__getattribute__
44147656
__getattribute__
12643664

Когда комментарий __getattr__:

...
##        def __getattr__(self,key):
##            print(key)
##            return super().__getattr__(key)
...

Результаты вывода:

id(a.__getattribute__)
__getattribute__
11005264
__getattribute__
11005264
__getattribute__
11005264
__getattribute__
11005264

1 Ответ

0 голосов
/ 28 октября 2018

Каждый раз, когда вы выполняете поиск instance.method, вы всегда получаете новый объект связанного метода.Эта привязка - то, как аргумент self передается функции (поиск метода связывает экземпляр с функцией, которая была в словаре классов).

Получаете ли вы метод с тем же id или не связано с тем, как Python вычисляет эти id значения.Значения, которые вы получаете от id, гарантированно будут уникальными, но только среди объектов, которые существуют одновременно.После того, как один объект собран мусором, может быть создан другой объект с таким же идентификатором.

CPython создает id s на основе адреса памяти объекта.Одна и та же память часто используется повторно для разных объектов связанных методов в разное время, поскольку кэшируемая память намного быстрее, чем всегда, используя новую память.Точно, когда это повторное использование происходит, является деталью реализации.Другие интерпретаторы Python (например, PyPy или Jython) и даже другие версии CPython могут делать это иначе или не делать это вообще.Вы никогда не должны полагаться на конкретные детали этого поведения (или любые другие подробности конкретных значений, которые вы получаете из id). only вещь, на которую вы должны положиться id, заключается в том, что она всегда будет отличаться для объектов, которые существуют одновременно.

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

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