1

我不清楚使用@property(优点和缺点)。我想问一些使用在Martijn帮助下构建的类的示例。

数据(文本格式)始终具有xyz来表征一个点(文本文件的 1、2 和 3 列)。有时我有一个“ classification”(第 4 列)属性和/或 location(第 5 列)。取决于文件的处理方式(有时更多属性)。

class Point(object):
    __slots__= ("x", "y", "z", "data", "_classification")
    def __init__(self, x, y, z):
        self.x = float(x)
        self.y = float(y)
        self.z = float(z)
        self.data = [self.x,self.y,self.z]

    @property
    def classification(self):
        return getattr(self, '_classification', None)

    @classification.setter
    def classification(self, value):
        self._classification = value
        if value:
            self.data = self.data[:3] + [value]
        else:
            self.data = self.data[:3]

    def __len__(self):
        return len(self.data)


p = Point(10,20,30)
len(p)
3
p.classification = 1
len(p)
4
p.data
[10.0, 20.0, 30.0, 1]

我希望添加locationwhenclassification已经设置,以了解使用@property. 我尝试使用以下代码,但我不知道这是否是 pythonic:

class Point(object):
    __slots__= ("x", "y", "z", "data", "_classification",'_location')
    def __init__(self, x, y, z):
        self.x = float(x)
        self.y = float(y)
        self.z = float(z)
        self.data = [self.x,self.y,self.z]

    @property
    def classification(self):
        return getattr(self, '_classification', None)

    @classification.setter
    def classification(self, value):
        self._classification = value
        if value:
            self.data = self.data[:3] + [value]
        else:
            self.data = self.data[:3]

    @property
    def location(self):
        return getattr(self, '_location', None)

    @location.setter
    def location(self, value):
        self._location = value
        if value:
            self.data = self.data[:4] + [value]
        else:
            self.data = self.data[:4]

    def __len__(self):
        return len(self.data)



p = Point(10,20,30)
p.classification = 1
p.data
[10.0, 20.0, 30.0, 1]
p.location = 100
p.data
[10.0, 20.0, 30.0, 1, 100]


p = Point(10,20,30)
p.location = 100
p.data
[10.0, 20.0, 30.0, 100]
4

1 回答 1

3

因此,您的课程有效,您只是在询问它是否是 Pythonic。我不是专家,但我会向您推荐 Python 之禅

显式优于隐式。

对我来说,当您设置一个属性(位置、分类)并最终默默地修改其他属性时,这是隐式的,而不是显式的。我认为一个更好、更清晰理解的用例是拥有类似assign_location和/或assign_classification方法的东西。这样,使用 API 的人就可以知道他不仅仅是在设置一个属性,而是在调用一个函数,该函数有一个解释其作用的文档字符串。

至于房产的哲学是什么,我不确定它的包含是否基于哲学。物业装饰师所做的就是摆脱这样难看的东西:

class Foo:
    def __getattr__(self, attr):
        if attr == 'location':
            ...
        elif attr == 'classification':
            ...

我非常喜欢的一种用途是使用属性来确保线程安全。例如:

class Foo(object):
    def __init__(self):
        self.lock = threading.Lock()
    @property
    def classification(self):
        return self.classification

    @classification.setter
    def classification(self, value):
        with self.lock:
            (something else thread-protected)
            self.classification = value

最后,还有一条建议。除非您知道为什么要使用插槽,否则不要。除非您知道为什么需要插槽,否则您不需要它们。

于 2013-02-28T17:29:31.280 回答