需要设计模式建议
Need Design Pattern Suggestion
我需要帮助来美化这段代码:)
definesAction 方法将根据参数调用 Class。考虑到 Class 是相似的,有一些方法可以概括这段代码。
提前致谢
主要Class
def defineAction(args):
if args.classabc is not None:
for host in config.getList('ABC', 'hosts'):
class_abc = ClassABC(config.getConfigs('ABC', host), args.version[0], user, password)
class_abc.action(args.classabc)
if args.classxyz is not None:
for host in config.getList('XYZ', 'hosts'):
class_xyz = ClassXYZ(config.getConfigs('XYZ', host), args.version[0], user, password)
class_xyz.action(args.classxyz)
# ...
def main():
parser.add_argument('--classabc', choices=['cmd'])
parser.add_argument('--classxyz', choices=['cmd'])
# ...
args = parser.parse_args()
defineAction(args)
亚Class亚
class ClassABC:
def __init__(self, configs, user, password):
self.hostConfigs = configs['host']
self.host_username = user
self.host_password = password
def a_method(self):
# This Method is equal in all subclasses
def b_method(self):
# This Method is different all subclasses
def action(self, action):
self.a_method()
self.b_method()
if action == 'cmd':
self.execute_cmd()
配置文件
[ABC]
hosts=abc_host1
var_abc=value1
[XYZ]
hosts=xyz_host1,xyz_host2
var_xyz=value2
我假设这些开关是互斥的(在这种情况下你真的想使用 mutually exclusive argument group)。
您希望 argparser 操作设置 class。如果您的命令行开关不需要任何参数,那么我会在这里使用 action="store_const"
:
parser.add_argument(
'--classabc', dest="class_", const=ClassABC,
action="store_const")
parser.add_argument(
'--classxyz', dest="class_", const=ClassXYZ,
action="store_const")
在解析时,当使用一个或另一个开关时,上述操作将 args.class_
设置为 ClassABC
或 ClassXYZ
。给 classes 一个 class 方法或一个属性来确定要查看的配置部分,不要在其他任何地方硬编码这些名称。
例如,如果两个 class 都有一个 config_section
属性,(ClassABC
设置为 'ABC'
,[=23= 设置为 'XYZ'
]), 然后你可以在你的循环创建实例中使用该属性:
if args.class_:
for host in config.getList(class_.config_section, 'hosts'):
instance = args.class_(config.getConfig(class_.config_section, host), ...)
想法是不根据 args
属性进行切换,您可以将其留给 argparse
,因为它已经为您确定了不同的选项。
如果两个命令行开关都需要额外的参数,则创建一个自定义 Action
subclass:
class StoreClassAction(argparse.Action):
def __call__(self, parser, namespace, values, **kwargs):
setattr(namespace, self.dest, (self.const, values)
然后将其用作:
parser.add_argument(
'--classabc', dest="class_", choices=['cmd'], const=ClassABC,
action=StoreClassAction)
parser.add_argument(
'--classxyz', dest="class_", choices=['cmd'], const=ClassXYZ,
action=StoreClassAction)
现在 args.class_
参数设置为 (classobject, argumentvalue)
,因此您可以使用:
if args.class_:
cls, action = args.class_
for host in config.getList(cls.config_section, 'hosts'):
instance = args.class_(config.getConfig(cls.config_section, host), ...)
instance.action(action)
我需要帮助来美化这段代码:) definesAction 方法将根据参数调用 Class。考虑到 Class 是相似的,有一些方法可以概括这段代码。 提前致谢
主要Class
def defineAction(args):
if args.classabc is not None:
for host in config.getList('ABC', 'hosts'):
class_abc = ClassABC(config.getConfigs('ABC', host), args.version[0], user, password)
class_abc.action(args.classabc)
if args.classxyz is not None:
for host in config.getList('XYZ', 'hosts'):
class_xyz = ClassXYZ(config.getConfigs('XYZ', host), args.version[0], user, password)
class_xyz.action(args.classxyz)
# ...
def main():
parser.add_argument('--classabc', choices=['cmd'])
parser.add_argument('--classxyz', choices=['cmd'])
# ...
args = parser.parse_args()
defineAction(args)
亚Class亚
class ClassABC:
def __init__(self, configs, user, password):
self.hostConfigs = configs['host']
self.host_username = user
self.host_password = password
def a_method(self):
# This Method is equal in all subclasses
def b_method(self):
# This Method is different all subclasses
def action(self, action):
self.a_method()
self.b_method()
if action == 'cmd':
self.execute_cmd()
配置文件
[ABC]
hosts=abc_host1
var_abc=value1
[XYZ]
hosts=xyz_host1,xyz_host2
var_xyz=value2
我假设这些开关是互斥的(在这种情况下你真的想使用 mutually exclusive argument group)。
您希望 argparser 操作设置 class。如果您的命令行开关不需要任何参数,那么我会在这里使用 action="store_const"
:
parser.add_argument(
'--classabc', dest="class_", const=ClassABC,
action="store_const")
parser.add_argument(
'--classxyz', dest="class_", const=ClassXYZ,
action="store_const")
在解析时,当使用一个或另一个开关时,上述操作将 args.class_
设置为 ClassABC
或 ClassXYZ
。给 classes 一个 class 方法或一个属性来确定要查看的配置部分,不要在其他任何地方硬编码这些名称。
例如,如果两个 class 都有一个 config_section
属性,(ClassABC
设置为 'ABC'
,[=23= 设置为 'XYZ'
]), 然后你可以在你的循环创建实例中使用该属性:
if args.class_:
for host in config.getList(class_.config_section, 'hosts'):
instance = args.class_(config.getConfig(class_.config_section, host), ...)
想法是不根据 args
属性进行切换,您可以将其留给 argparse
,因为它已经为您确定了不同的选项。
如果两个命令行开关都需要额外的参数,则创建一个自定义 Action
subclass:
class StoreClassAction(argparse.Action):
def __call__(self, parser, namespace, values, **kwargs):
setattr(namespace, self.dest, (self.const, values)
然后将其用作:
parser.add_argument(
'--classabc', dest="class_", choices=['cmd'], const=ClassABC,
action=StoreClassAction)
parser.add_argument(
'--classxyz', dest="class_", choices=['cmd'], const=ClassXYZ,
action=StoreClassAction)
现在 args.class_
参数设置为 (classobject, argumentvalue)
,因此您可以使用:
if args.class_:
cls, action = args.class_
for host in config.getList(cls.config_section, 'hosts'):
instance = args.class_(config.getConfig(cls.config_section, host), ...)
instance.action(action)