0

これは醜い、メンテナンスの多い工場です。文字列を使用して、文字列と一致する名前のオブジェクトをインスタンス化する方法が本当に必要です。メタクラスが答えだと思いますが、それを適用する方法がわかりません。

from commands.shVersionCmd import shVersionCmd
from commands.shVRFCmd import shVRFCmd
def CommandFactory(commandnode):
    if commandnode.attrib['name'] == 'shVersionCmd': return shVersionCmd(commandnode)        
    if commandnode.attrib['name'] == 'shVRFCmd': return shVRFCmd(commandnode)
4

4 に答える 4

2

globals()dictを返す関数を使用してグローバル名を検索できます。

from commands.shVersionCmd import shVersionCmd
from commands.shVRFCmd import shVRFCmd

# An explicit list of allowed commands to prevent malicious activity.
commands = ['shVersionCmd', 'shVRFCmd']

def CommandFactory(commandnode):
    cmd = commandnode.attrib['name']
    if cmd in commands:
        fn = globals()[cmd]
        fn(commandnode)
于 2013-02-23T13:46:40.933 に答える
0

私の個人的な好みは、各コマンドが自身をファクトリに登録するように、ファクトリとコマンドの実装の間の依存関係を変えることです。

実装例:

ファイル コマンド/__init__.py:

import pkgutil
import commands

_commands = {}

def command(commandCls):
    _commands[commandCls.__name__] = commandCls
    return commandCls

def CommandFactory(commandnode):
    name = commandnode.attrib['name']
    if name in _commands.keys():
        return _commands[name](commandnode)

# Load all commands
for loader, module_name, is_pkg in  pkgutil.walk_packages(commands.__path__):
    if module_name!=__name__:
        module = loader.find_module(module_name).load_module(module_name)

ファイル commands/mycommand.py:

from commands import command

@command
class MyCommand(object):    
    def __init__(self, commandnode):
        pass

小さなテスト:

from commands import CommandFactory

# Stub node implementation
class Node(object):
    def __init__(self, name):
        self.attrib = { "name": name }

if __name__=='__main__':
    cmd = CommandFactory(Node("MyCommand"))
    assert cmd.__class__.__name__=="MyCommand", "New command is instance of MyCommand"
    cmd = CommandFactory(Node("UnknownCommand"))
    assert cmd is None, "Returns None for unknown command type"
于 2013-02-23T14:33:34.607 に答える
0

この回答How to make an anonymous function in Python without Christening it? キーに基づいてコードのブロックをきれいに呼び出す方法について説明します

于 2013-02-23T13:27:16.933 に答える
0

eval is your friend:

from commands import *
def CommandFactory(commandnode):
    name=commandnode.attrib['name']
    assert name in ( "shVersionCmd", "shVRFCmd" ), "illegal command"
    return eval(name+"."+name)(commandnode)

Note that if you are sure that name will never contain any illegal commands, you could remove the assert and turn the function into a no-maintenance-delight. In case of doubt, leave it in and maintain the list in a single place.

于 2013-02-23T13:14:22.490 に答える