Python 在实践中,是否应该使一个类的所有对象都具有相同数量的属性?

Python 在实践中,是否应该使一个类的所有对象都具有相同数量的属性?,python,class,coding-style,Python,Class,Coding Style,哪一种是更好的编码实践 以下示例(用python编写): 现在,如果过滤器中的第一个标记不是数字,那么类的对象将只有一个属性-索引 上面的类可能有数百个属性。在这种情况下,哪一种编码方式更好—— 使所有对象具有相同数量的属性。(即,在构造函数顶部定义所有属性,为它们提供一些默认值或其他值) 或 另一种方式(如上面的示例所示) 例如 唯一真正的区别在于使用类的代码。似乎任何此类代码都可能如下所示: if sample_instance.indexed and sample_instance.val

哪一种是更好的编码实践

以下示例(用python编写):

现在,如果过滤器中的第一个标记不是数字,那么类的对象将只有一个属性-索引

上面的类可能有数百个属性。在这种情况下,哪一种编码方式更好——

使所有对象具有相同数量的属性。(即,在构造函数顶部定义所有属性,为它们提供一些默认值或其他值)

另一种方式(如上面的示例所示)

例如


唯一真正的区别在于使用类的代码。似乎任何此类代码都可能如下所示:

if sample_instance.indexed and sample_instance.valid: # 'valid' reads better
    protocol = sample_instance.protocol
因此,在
.indexed==False
的情况下,是否存在
.valid
.protocol
或是否具有任何特定值并不重要

如果您希望调用代码返回属性(即使只是
None
),不管是什么情况,您都可以为任何未直接解析的属性实现
\uuu getattr\uuuu
to
return 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