Перенаправление определений функций в python

StackOverflow https://stackoverflow.com/questions/682822

  •  22-08-2019
  •  | 
  •  

Вопрос

Это очень надуманный пример, поскольку нелегко объяснить контекст, в котором я в конечном итоге реализовал это решение.Однако, если кто-нибудь может ответить, почему происходит именно эта особенность, я был бы благодарен.

Пример:

class A(dict):  
    def __init__(self):
        self['a'] = 'success'

    def __getitem__(self, name):
        print 'getitem'
        return dict.__getitem__(name)

class B(object):
    def __init__(self):
        self._a = A()
        setattr(self, '__getitem__', self._a.__getitem__) 

b = B()
c = b['a']

Это выводит:

c = b['a']
TypeError: 'B' object is unsubscriptable

Несмотря на то, что это странный способ сделать это (очевидно, что разделение на подклассы было бы более логичным), почему он не находит метод, который я явно установил?

Если я сделаю это:

dir(b)

Я понимаю это:

['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_a']

Та же проблема возникает и с другими методами, такими как __iter__.Что такого в явном определении этого метода, который работает?

Это было полезно?

Решение

Когда вы используете скобки [] python заглядывает в класс.Вы должны установить метод в классе.

Вот адаптированный вами код:

class A(dict):  
    def __init__(self):
        self['a'] = 'success'

    def __getitem__(self, name):
        print 'getitem!'
        return dict.__getitem__(self, name)

class B(object):
    def __init__(self):
        self._a = A()
        B.__getitem__ = self._a.__getitem__

b = B()
c = b['a']

Другие советы

Это происходит потому, что вы не можете переопределить специальные методы класса "на лету".

Я не смог найти ссылку на это, но в основном потому, что они являются методами класса и им не разрешено быть методами экземпляра.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top