Перенаправление определений функций в python - PullRequest
2 голосов
/ 25 марта 2009

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

Пример:

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__. Что это за явное определение этого метода, который работает?

Ответы [ 2 ]

7 голосов
/ 25 марта 2009

При использовании скобок [] 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']
1 голос
/ 25 марта 2009

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

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

...