2008-11-18 3 views
1

У меня есть проект плавкого предохранителя на основе примера Xmp в документации на предохранители. Я включил небольшой фрагмент кода, чтобы показать, как это работает. По какой-то причине get_file вызывает вызов, и класс создается, но вместо того, чтобы использовать fuse, вызывающий .read() в классе из get_file (file_class), плагин продолжает вызывать Dstorage.read(), который побеждает цель в перемещении функции чтения из этого класс.Почему плавкий предохранитель не используется в классе, указанном в файле_файле

class Dstorage(Fuse, Distributor): 
    def get_file(self, server, path, flags, *mode): 
     pass 
     # This does some work and passes back an instance of 
     # a class very similar to XmpFile 

    def main(self, *a, **kw): 
     self.file_class = self.get_file 
     return Fuse.main(self, *a, **kw) 

У меня есть код, размещенный на стартовой панели, вы можете скачать его с помощью этой команды.
BZR совместно https://code.launchpad.net/~asa-ayers/+junk/dstorage
BZR филиала LP: ~ Asa-Айерс/dstorage/багажник

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

ответ

1

Глядя на коде класса предохранителей (который представляет собой лабиринт извилистых маленьких отрывков, создающие методы прокси), я вижу этот бит (что замыкание используется для создания сеттера внутри Fuse.MethodProxy._add_class_type, строка 865):

 def setter(self, xcls): 

      setattr(self, type + '_class', xcls) 

      for m in inits: 
       self.mdic[m] = xcls 

      for m in proxied: 
       if hasattr(xcls, m): 
        self.mdic[m] = self.proxyclass(m) 

Когда вы делаете self.file_class = self.get_file, это вызывается с помощью self.get_file, который является связанным методом. Цикл над прокси-атрибутами ожидает, что он сможет получить атрибуты из установленного вами класса, чтобы поместить их в свой прокси-словарь после их переноса, но их там нет, потому что это связанный метод, а не класс. Так как он не может их найти, он возвращается к вызову на Dstorage.

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

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