构建这个简单工厂 class 的更 pythonic 方法是什么?

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

前言: 我是 Python 的新手。我一般写PHP。我也知道这可能被认为是一个主观问题,它可能会被标记为这样,但我确实认为可以从中得出一个答案,即 "correct enough",它肯定会对我有所帮助。我也不知道还能问哪里。

现在,这只是播放代码,但我当时的想法是拥有某种静态工厂,根据选项构建 Paramiko SSHClient class。我不确定我最终将如何设计它,但我有一种强烈的感觉,即使是现在我也没有充分利用 python 设计功能,而是强迫它像 PHP 那样工作.基本上,我做错了吗

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

编辑: 只是为了清楚地说明我最终要完成的事情——我可能想为通用 unix / linux 主机构建 paramiko sshclients,但也希望能够为怪人构建专门的 sshclient classes,例如没有 运行 real shell 的 Cisco 交换机。为此,我必须传递额外的选项来禁用分页,有时 sleep 在命令之间,等等,具体取决于远程 "shell".

的性质

你应该知道NoneType Error
special 不在 options 中时 options.get('special').get('auto_add_policy') 会抛出异常,因为你不能做 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)

您可以在您的目的中导出 SSHClient,并在默认情况下为 look_for_key = True 删除 default_connect_opts

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)