2012-02-22 2 views
2

Мне нужно работать с удаленными файлами прозрачно, как если бы они были локальными файлами в некотором питонном коде, который я пишу, поэтому я решил использовать SFTP для этой задачи. Следующий пример кода работает (он печатает первую строку удаленного файла):Создание класса многократного использования в python

import paramiko 

client = paramiko.SSHClient() 
client.load_system_host_keys() 
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
client.connect(hostname='192.168.8.103', username='root', password='pyjamas') 
sftp = client.open_sftp() 
test = sftp.open('/var/log/example/ingest.log', mode='r', bufsize=1) 
print test.readline() 

я собираюсь подключаться ко многим файлам, поэтому я решил написать класс, который дает мне объект SFTPFile. Изучите следующий код:

import paramiko 

class RemoteLog(object): 
    """This class implements the remote log buffer.""" 

    def __init__(self, host, user='', pw='', log=''): 
     """Initializes a connection to a remote log.""" 

     client = paramiko.SSHClient() 
     client.load_system_host_keys() 
     client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
     client.connect(hostname=host, username=user, password=pw) 
     sftp = client.open_sftp() 
     self.log = sftp.open(log, mode='r', bufsize=1) 

if __name__ == "__main__": 
    test = RemoteLog(host='192.168.8.103', user='root', pw='pyjamas', log='/var/log/example/ingest.log') 
    print test.log.readline() 

К сожалению, readline() в этом сценарии ничего не возвращает. Нет никаких ошибок или очевидных объяснений.

Как воспроизвести функциональность из моего первого фрагмента кода в класс многократного использования?

+4

Попробуйте использовать ссылку sftp и client ('self.client = paramiko ...' и 'self.sftp = self.client.open_sftp()'). Мое единственное предположение: когда они выходят из сферы действия, они автоматически очищают и закрывают соединение. – gfortune

+0

, если вы добавите 'print self.log.readline()' inside '__init__', вы получаете то, что ищете? @gfortune та же идея :-) – Simon

+0

@gfortune: похоже, это сделано! Похоже, что они очистили соединение после потери объема, проверка этого соединения на другом конце показала бы это. – Stealthii

ответ

2

Похоже, что соединение sftp закрывается, когда переменные выходят из области действия в __init__. Сохранение ссылки на тех, кто в классе, устраняет проблему.

def __init__(self, host, user='', pw='', log=''): 
    """Initializes a connection to a remote log.""" 

    self.client = paramiko.SSHClient() 
    self.client.load_system_host_keys() 
    self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
    self.client.connect(hostname=host, username=user, password=pw) 
    self.sftp = self.client.open_sftp() 
    self.log = self.sftp.open(log, mode='r', bufsize=1) 

В качестве дополнительной рекомендации вы можете рассмотреть возможность реализации стандартных функций файлового объекта и скрыть ссылку self.log за своим объектом. Вместо test.log.readline() вы действительно должны иметь возможность использовать test.readline(), поскольку вы пытаетесь обернуть файл-подобный объект (вам действительно нужно реализовать метод close()). Там немного работы, но это одноразовая работа и сделает код, который использует этот класс намного чище.

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