Изменить экземпляр объекта C на подкласс Python - PullRequest
2 голосов
/ 29 сентября 2011

Можно ли изменить класс объекта C на подкласс Python?

Я использую PyGTK, и у меня есть ListModel, в который я поместил свой собственный класс, но я хочу превратить его в TreeModelFilter. Инструкции говорят мне, чтобы создать его, выполнив:

class MyListStore(gtk.ListStore):
  def __init__(self, title):
    self.title = title

liststore = MyListStore(gobject.TYPE_INT, gobject.TYPE_STRING)
modelfilter = liststore.filter_new()

Так что я подумал, что могу просто создать:

class MyFilteredListStore(gtk.TreeModelFilter):
  def __init__(self, title):
    self.title = title

Но я не знаю, как использовать filter_new для использования моего класса вместо gtk.TreeModelFilter.

Ответы [ 2 ]

1 голос
/ 29 сентября 2011

Лучший способ решить эту проблему - не создавать подкласс TreeModel, а назначать переменную объекту, который может быть ListStore или TreeModelFilter.

class MyListStore(object):
  def __init__(self, title, filter=None):
    self.title = title
    self._model = gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING)
    if filter_func:
      self._model = self.model.filter_new()
      self._model.set_visible_func(filter)

Я думаю, что это лучший способ обойти это.

Редактировать

Для всех, кто заинтересовался, я обнаружил, что следующее поможет избежать взлома старого кода. Он действует как наследование, фактически не делая этого:

  def __getattr__(self, name):
    'Get the attribute from the model if possible.'
    if hasattr(self._model, name):
      return getattr(self._model, name)
    if isinstance(self._model, gtk.TreeModelFilter):
      if hasattr(self._model.get_model(), name):
        return getattr(self._model.get_model(), name)
1 голос
/ 29 сентября 2011

Наследование может быть очень гибким понятием в Python.Для начала вы всегда должны использовать новые классы стилей.Для этого убедитесь, что ваши классы всегда наследуются от «объекта».

Важно отметить, что классы должны наследовать от других классов, а не экземпляров других классов, поэтому ваш пример действительно не сработает там.На самом деле, я не вижу разницы между наследованием от X или x1.

Наследование в python тесно связано с «Порядком разрешения методов» (MRO).Вы можете просматривать объекты MRO с помощью модуля проверки.

>>> import inspect
>>> import pprint
>>>
>>> class X(object):
...     pass
...
>>> class Y(X):
...     pass
...
>>>
>>> pprint.pprint(inspect.getmro(Y))
(<class '__main__.Y'>, <class '__main__.X'>, <type 'object'>)
>>> 

Кортеж в конце показывает порядок, в котором python будет пытаться разрешать вызовы методов и атрибутов.Вы можете изменить MRO во время выполнения, изменив атрибут __bases__ класса.

>>> Y.__bases__
(<class '__main__.X'>,)
>>>
>>> class Z(object):
...     pass
...
>>> Y.__bases__ = tuple([Z])
>>> pprint.pprint(inspect.getmro(Y))
(<class '__main__.Y'>, <class '__main__.Z'>, <type 'object'>)
>>>

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

...