Gianni Spear
Gianni Spear

Reputation: 7924

using @property to build a class in Python

I am not clear on the use of @property (advantages and disadvantages). I want to ask for some example using this class built with the help of Martijn.

The data (in text format) always has a x,y, and z to characterize a point (1, 2, and 3 columns of text file). Sometimes I have a "classification" (4th column) attribute and/or location (5th column). Depending on how the file is processed (sometimes more attributes).

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]

I wish to add location when classification is already set in order to understand the philosophy of using a @property. I tried with the following code but I don't know if this is pythonic or not:

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]

Upvotes: 1

Views: 257

Answers (1)

Ken Kinder
Ken Kinder

Reputation: 13120

So, your class works, and you're just asking whether it's Pythonic. I'm not an expert, but I will refer you to the Zen of Python:

Explicit is better than implicit.

To me, when you set one property (location, classification) and it ends up silently modifying other attributes, that is implicit, not explicit. I think a better, more cleanly understood use case would be to have something like an assign_location and/or assign_classification methods. That way the person using the API can know that he's not just setting an attribute, he's calling a function that has a docstring explaining what it does.

As for what the philosophy of the property is, I'm not sure its inclusion was based so much on philosophy. What the property decorator did was get rid of unsightly things like this:

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

One use I'm quite fond of is using properties to make things thread safe. For example:

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

Finally, another piece of advice. Unless you know why you're using slots, don't. Unless you know why you need slots, you don't need them.

Upvotes: 3

Related Questions