Python 在实践中,是否应该使一个类的所有对象都具有相同数量的属性?
哪一种是更好的编码实践 以下示例(用python编写): 现在,如果过滤器中的第一个标记不是数字,那么类的对象将只有一个属性-索引 上面的类可能有数百个属性。在这种情况下,哪一种编码方式更好—— 使所有对象具有相同数量的属性。(即,在构造函数顶部定义所有属性,为它们提供一些默认值或其他值) 或 另一种方式(如上面的示例所示) 例如Python 在实践中,是否应该使一个类的所有对象都具有相同数量的属性?,python,class,coding-style,Python,Class,Coding Style,哪一种是更好的编码实践 以下示例(用python编写): 现在,如果过滤器中的第一个标记不是数字,那么类的对象将只有一个属性-索引 上面的类可能有数百个属性。在这种情况下,哪一种编码方式更好—— 使所有对象具有相同数量的属性。(即,在构造函数顶部定义所有属性,为它们提供一些默认值或其他值) 或 另一种方式(如上面的示例所示) 例如 唯一真正的区别在于使用类的代码。似乎任何此类代码都可能如下所示: if sample_instance.indexed and sample_instance.val
唯一真正的区别在于使用类的代码。似乎任何此类代码都可能如下所示:
if sample_instance.indexed and sample_instance.valid: # 'valid' reads better
protocol = sample_instance.protocol
因此,在.indexed==False
的情况下,是否存在.valid
或.protocol
或是否具有任何特定值并不重要
如果您希望调用代码返回属性(即使只是None
),不管是什么情况,您都可以为任何未直接解析的属性实现\uuu getattr\uuuu
toreturn None
不过,我建议将字符串解析从
\uuuu init\uuuu
中移出;考虑有一个类方法来代替它。此外,您正在同一方法中混合不同的逻辑位。与之相比:
class SampleClass(object):
PROTOCOLS = {'ip': do_this_to_ip,
'tcp': but_this_to_tcp}
def __init__(self, indexed=False, action=None, protocol=None):
self.indexed = indexed
self.action = action
self.protocol = protocol
@property
def valid(self):
return self.protocol in self.PROTOCOLS
@classmethod
def from_string(cls, filter_): # avoid shadowing the built-in
filter_ = filter_.split()
if not filter_[0].isdigit():
return cls()
return cls(True, filter_[1], filter_[2])
其使用方式如下:
>>> sample = SampleClass.from_string("10 permit ip")
>>> sample.valid
True
>>> sample.protocol
'ip'
>>> sample2 = SampleClass.from_string("foo bar")
>>> sample2.valid
False
<>最后,一个更广泛的问题应该是:如果实例将是如此的不同,它们是否应该是同一个类?为什么你使用<代码> 0 < /代码>和<代码> 1 < /代码>而不是<代码>真< /代码>和<代码> false < /代码>?整个
filter
是否只是布尔属性的一系列标志?所有属性都有默认值吗?是否有一些人依赖其他人?您何时访问属性?@jornsharpe filter是一个信息字符串。根据这些属性初始化属性。并非所有属性都相互依赖。如果我没有为所有属性设置默认值,它们可以是“n/a”或类似的类型。你能提供几个稍微少一点的过滤器的示例吗?它会发生什么?你为什么要这样初始化。只需存储过滤器字符串。为什么它是一个字符串?@TonyHopkinson,因为过滤器中的信息将在以后使用,不是作为字符串,而是以片段的形式使用。我不在乎字符串是否被索引,它只会在字符串被索引时困扰我。按原样存储管柱将导致以后的操作并发症。我寻求对更好的编码风格的意见。
class SampleClass(object):
PROTOCOLS = {'ip': do_this_to_ip,
'tcp': but_this_to_tcp}
def __init__(self, indexed=False, action=None, protocol=None):
self.indexed = indexed
self.action = action
self.protocol = protocol
@property
def valid(self):
return self.protocol in self.PROTOCOLS
@classmethod
def from_string(cls, filter_): # avoid shadowing the built-in
filter_ = filter_.split()
if not filter_[0].isdigit():
return cls()
return cls(True, filter_[1], filter_[2])
>>> sample = SampleClass.from_string("10 permit ip")
>>> sample.valid
True
>>> sample.protocol
'ip'
>>> sample2 = SampleClass.from_string("foo bar")
>>> sample2.valid
False