是否真的一旦在Python中使用属性,它总是更好地通过属性初始化?

时间:2016-11-02 21:22:28

标签: python class oop properties private-members

我曾经在__init__中初始化私有属性,如下所示(这种初始化方式也常见),

class Duck():
    def __init__(self, input_name): 
        self.__name = input_name

        @property 
        def name(self): 
            return self.__name 

        @name.setter 
        def name(self, input_name): 
            self.__name = input_name

        # Use private attribute __name internally for other purposes below...

但我只是想确保在最开始使用属性__init__实际上是否更安全,例如,在下一个示例中,对于大于1000或小于0的输入,我想要评估分别为1000和0,而不是原始输入值。我似乎无法使用self.__x = x

class P:
    def __init__(self,x):
        # If self.__x = x, not desirable
        self.x = x 

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, x):
        if x < 0:
            self.__x = 0
        elif x > 1000:
            self.__x = 1000
        else:
            self.__x = x

1 个答案:

答案 0 :(得分:-2)

我假设你使用python2。旧式类不支持属性。只需将第一行更改为

即可
class P(object):

无论您使用self._x还是self.__x后面的属性都无关紧要。只需将其一致,即将构造函数行更改回

self.__x = x

请勿将self.x称为属性。

修改 我认为存在误解。这里提出完整的代码:

class P(object):
    def __init__(self,x):
        self.__x = x

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, x):
        if x < 0:
            self.__x = 0
        elif x > 1000:
            self.__x = 1000
        else:
            self.__x = x

p = P(3)
p.x = 1001
print p.x

编辑2 - 实际问题: 我很抱歉,在这里根本没有掌握标题和实际问题,而是专注于让你的班级工作。我分心的是,如果你在python2中并使用旧式类,那么setter就不会被调用。

然后如下面的评论对话所示,我对是否初始化属性或属性没有明确答案,但我(个人)会说:

一个。如果初始化应该进行与执行相同的验证     setter,然后使用属性,否则你需要复制     制定者代码。

湾但是,如果初始化的值不需要验证(for     例如,您将其设置为先验验证的常量默认值     价值),然后没有理由使用该属性。