2017-02-04 2 views
2

Я хотел бы прокси «все» методы класса, используя следующий код:Как проксировать методы класса динамически?

import paramiko 

class SFTPProxy(): 
    def __init__(self, sftp): 
     self.sftp = TRANSPORT.open_sftp_client() 
     for x, y in type(self.sftp).__dict__.items(): 
      if re.search(r'^__', x): 
       continue 
      def fn(self, *args, **kwargs): 
       return y(self.sftp, *args, **kwargs) 
      setattr(SFTPProxy, x, fn) 

Когда я вызываю метод, как это:

fooproxy.sftp.listdir() 

Он работает.

Когда я вызываю метод, как это:

fooproxy.listdir() # this is the method belongs to the proxied class 

Программа просто зависает, есть ли какие-либо мелкие проблемы в коде?

+0

только для справки, почему обычное наследование не в порядке? – Marat

+0

@Marat Прокси обычно должен что-то делать до/после вызова исходного метода, похоже, что он оставил это, чтобы упростить пример. – Barmar

+0

@Barmar, и вы можете вызвать super() из унаследованных методов. Итак, почему этот подход? – Marat

ответ

1

Одна проблема, которую я вижу с вашим подходом, заключается в том, что не все значения в type(self.sftp).__dict__ являются функциями. Следовательно, y(...) не удастся. Не проще и чище переопределить __getattr__:

class SFTPProxy(object): 
    def __init__(self, sftp): 
     self.sftp = TRANSPORT.open_sftp_client() 

    def __getattr__(self, item): 
     if hasattr(self.sftp, item): 
      return getattr(self.sftp, item) 
     raise AttributeError(item) 

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

Смежные вопросы