Создание повторно используемого класса в Python - PullRequest
2 голосов
/ 22 февраля 2012

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

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 () в этом сценарии ничего не возвращает. Там нет ошибок или очевидных объяснений.

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

1 Ответ

2 голосов
/ 22 февраля 2012

Похоже, что соединение 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()). Для этого нужно немного поработать, но это одноразовое усилие, которое сделает код, который использует этот класс, намного чище.

...