我的情况是一个对象有15个以上的参数,其中一些是强制/可选/有默认值/没有默认值。我们假设课程为Foo
,并且参数为Bar1
,Bar2
,...,BarN
。
我可以像以下那样对课程进行编程:
传统的,乏味的方式。易于定义默认值和详细信息。但是,代码很长并且有很多重复。
class Foo(object):
def __init__(self, bar1, bar2,...barN='somedefault' ):
self.bar1 = bar1
self.bar2 = bar2
...
self.barN = barN
滥用(?)kwargs
。不支持默认值。
class Foo(object):
fields = [ 'bar1', 'bar2', ...n 'barN']
def __init__(self, **kwargs ):
for key in kwargs:
if key in self.fields:
setattr(self, key, kwargs[key])
else:
raise Exception('invalid attribute: {0}'.format(key))
对于数字2,我可以将fields
类属性更改为地图{ 'attribute_name': 'default_value' }
,然后如果该密钥不在default_value
中,则分配kwargs
。
我工作的背景是我创建的对象与服务器,防火墙规则,存储磁盘等对应,具有很多属性。在很多情况下,我从API获取属性,所以我可以做2号(即使没有验证)。但是,有时用户会创建防火墙规则,将其附加到服务器并将其发送到API(带有JSON正文的POST)。
是否有一些标准/ pythonic方式来处理具有大量属性的对象? #2中的方法看起来是否合适,或者我应该采用冗长的#1方式?
编辑:一个具体示例是具有以下参数的防火墙规则对象:
action
destination_address_end
destination_address_start
destination_port_end
destination_port_start
direction
family
icmp_type
position
protocol
source_address_end
source_address_start
source_port_end
source_port_start
现在我倾向于这样的事情:
class FirewallRule(object):
attributes = {
'action': 'default_value',
'destination_address_end': 'default_value',
'destination_address_start': 'default_value',
'destination_port_end': 'default_value',
'destination_port_start': 'default_value',
'direction': 'default_value',
'family': 'default_value',
'icmp_type': 'default_value',
'position': 'default_value',
'protocol': 'default_value',
'source_address_end': 'default_value',
'source_address_start': 'default_value',
'source_port_end': 'default_value',
'source_port_start': 'default_value'
}
def __init__(self, **kwargs ):
for key in kwargs:
valur_or_default = kwargs.get(key, attributes[key])
setattr(self, key, valur_or_default)
(在生产代码I' d显然添加了更好的错误处理和验证)
答案 0 :(得分:0)
我会将这些不同的属性组合在"属性集"捆绑它们是有意义的。为参数创建这些集合和手部实例的类。可以测试None
值,并且该"属性的默认实例设置"创建和分配。在该实例化期间,您可以同时提供给定对象(服务器,防火墙)的默认参数,但我通常会创建子类来处理该情况并使参数设置显式而不是隐藏在另一个非相关类中。
如果bar1
,bar2
和bar3
与您相关,那么
class Bar123:
def __init__(self, bar1=None, bar2=None, bar3=None):
self.bar1 = bar1
self.bar2 = bar2
self.bar3 = bar3
class ServerBar123:
def __init__(self, bar1=None, bar2=None, bar3=None):
self.bar1 = bar1 if bar1 else 25
self.bar2 = bar2 if bar2 else 75
self.bar3 = bar3
class ServerFoo:
def __init__(self, bar123=None, bar2=None, bar3=None, ....):
self.bar123 = bar123 if bar123 else ServerBar123()
if self.bar123.bar1 != 25:
....