简体   繁体   中英

What's a more pythonic way to build this simple factory class?

Preface: I'm very new to Python. I usually write PHP. I also know this might be considered a subjective question and it might be marked as such, but I do think an answer could emerge from this that is "correct enough" and it would certainly help me. Also I don't know where else to ask.

Right now, this is just play-code, but the idea I was playing with was to have some sort of static factory that builds a Paramiko SSHClient class based on options. I'm not sure how I'll design this ultimately, but I have a strong feeling that even now I'm not taking full advantage of python design features, and instead forcing it to work like PHP. Basically, Am I doing it wrong already?

import paramiko
import time
import sys

class Client:

    @staticmethod
    def build(host, **options):

        default_connect_opts = {'look_for_keys': True}
        client = paramiko.SSHClient()

        # automatically add untrusted hosts
        if options.get('special').get('auto_add_policy'):
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        our_connect_opts = options.get('connect');

        # merge defaults with provided with preference for provided opts
        connect_opts = dict(default_connect_opts.items() + our_connect_opts.items())
        #print connect_opts
        #sys.exit()

        client.connect(host, **connect_opts)
        return client

options = {
    'connect': {
        'username': 'root',
        'password': 'p4assw0rd',
        'look_for_keys': False,
    },
    'special': {
        'auto_add_policy': True,
    }
}
client = Client.build('10.0.0.13', **options)
print client

Edit: Just for clarity on what I'm trying to accomplish ultimately -- I will probably want to build paramiko sshclients for generic unix / linux hosts, but also want to be able to build specialized sshclient classes for oddballs like a Cisco switch that doesn't run a real shell. And to do that I have to pass additional options to disable paging, and sometimes sleep between commands, etc, depending on the nature of the remote "shell".

You should be aware of NoneType Error .
options.get('special').get('auto_add_policy') will throw exception when special not in options cauz you can't do None.get() .

    # Deal with `options` without key 'special'
    if options.get('special', {}).get('auto_add_policy'):
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    default_connect_opts.update(options.get('connect', {}))

    client.connect(host, **default_connect_opts)

You can derive SSHClient in your purpose, and get rid of default_connect_opts for look_for_key = True by default.

class Client(paramiko.SSHClient):

    def __init__(self, host, **options):
        super(Client, self).__init__()
        # set policy
        if options.get('special', {}).get('auto_add_policy'):
            self._policy = paramiko.AutoAddPolicy()
        # look_for_key = True by default
        self.connect(host, **options.get('connect', {}))

client = Client(host, **options)
new_client = Client(new_host, **new_options)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM