python класс зарезервированных методов - PullRequest
0 голосов
/ 05 апреля 2020

Я пишу python класс, который создает соединение с удаленным сервером с использованием библиотеки fabric2.

Мне интересно, какой дизайн письма подходит для моего класса.

для пример:

class SshToServer:
    """ssh connection to server."""

    def __init__(self, ip, user, ssh_key_path):
        self.ssh_client = Connection(
            host=ip,
            user=user,
            port=22,
            connect_kwargs={"key_filename": ssh_key_path},
            inline_ssh_env=True,
        )

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.ssh_client.close()

Сначала было бы здорово получить общую информацию раньше:

  1. Я должен использовать методы __enter__ и __exit__, только если я планирую создать объект с "с" оператором? есть ситуация, когда я выберу использование этих методов без "с" созданием оператора?

  2. Что означает использование обоих __init__ и __enter__ внутри учебный класс? какая разница между ними? потому что они оба запускаются, когда я создаю объект. использования одного из них достаточно? То же самое для использования методов класса __exit__ и __del__.

вернуться к моему коду:

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

, если среда X соединяется с сервером X - то же самое для среды Y:

with SshToServer(ip=BLA_1, user=BLA_1, ssh_key_path=BLA_1) as conn:
    do_stuff...
with SshToServer(ip=BLA_2, user=BLA+2, ssh_key_path=BLA_2) as conn:
    do_stuff...

, и это то же самое методы в обоих соединениях, это просто другой удаленный сервер.

, так что я предполагаю, что использование "с" не является разумным способом в этом случае (потому что я дублирую код).

Я хочу изменить способ создания объекта следующим образом:

conn = SshToServer(...) do_stuff... conn.__exit__ / conn.__del__

Но я путаю эти 4 метода и время их использования.

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020
Методы

__enter__ и __exit__ используются для выполнения действий по настройке и демонтажу. Он автоматически закроет соединение для вас. __exit__ вызывается при выходе из области действия with.

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

Я не знаю Класс соединения. если это позволяет вам настроить пользователя отдельно, тогда вы можете сделать это

with SshToServer(ip=BLA_1, ssh_key_path=BLA_1) as conn:
    conn.user = BLA_1
    // do some stuff
   conn.user = BLA_2
   // do some stuff
0 голосов
/ 05 апреля 2020
  1. Да, они предназначены только для использования с with.

  2. В вашем примере кода __init__ вызывается первым для создания (фактически только инициализировать) объект (как обычно), затем вызывается __enter__ для использования объекта в качестве диспетчера контекста (только в with). Оба метода имеют свои собственные применения.

Вызов специального Прямое использование методов обычно является плохой идеей. Исключение: вызов в специальном методе того же метода суперкласса.

Основное преимущество with заключается в том, что __exit__ вызывается практически при любых обстоятельствах и не может быть забытым.

В вашем коде вы можете, например, написать два with как один вроде

conn = SshToServer(...)  # Somehow select which object to create
with conn:
    do_stuff...

Это намного чище и безопаснее, чем прямой вызов специальных методов.

...