Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python read-only class properties

Is there a way to make read-only class properties in Python? Ex. in Unity3d you can do this:

transform.position = Vector3.zero

Vector3.zero returns an instance of the Vector3 class where x, y, and z are 0. This is basically the same as:

transform.position = Vector3(0, 0, 0)

I've tried doing something like this:

class Vector3(object):
    zero = Vector3(0, 0, 0)
    ...

But I get an undefined variable error because the class hasn't been defined yet. So how do you make read-only class properties that don't require an instance of the class?

like image 612
topher Avatar asked Sep 01 '11 16:09

topher


People also ask

What read only properties?

Read-only means that we can access the value of a property but we can't assign any value to it.

What is readonly Python?

READONLY¶ This fork on CPython 3.5 adds a machinery to be notified when the Python code is modified. Modules, classes (types) and functions are tracked. At the first modification, a callback is called with the object and the modified attribute. This machinery should help static optimizers.

What are read only list which Cannot be modified in Python?

Tuples are, for most intents and purposes, 'immutable lists' - so by nature they will act as read-only objects that can't be directly set or modified.

What are class properties in Python?

Class Properties The property() method in Python provides an interface to instance attributes. It encapsulates instance attributes and provides a property, same as Java and C#. The property() method takes the get, set and delete methods as arguments and returns an object of the property class.


1 Answers

The most obvious way might be to alter the class object after the fact:

class Vector3(object):
    # ...
Vector3.zero = Vector3(0, 0, 0)

The main problem with this is that there's then only one zero object, and if it's mutable you can cause accidental damage all over the place. It may be easier (and feel less hacky) to use a dynamic descriptor that creates a zero vector every time it's accessed (this is done by creating a ClassProperty class):

class ClassProperty(property):
    def __get__(self, cls, owner):
        return self.fget.__get__(None, owner)()

class Vector3(object):
    @ClassProperty
    @classmethod
    def zero(cls):
        return cls(0, 0, 0)

I consider none of these really "pythonic", though. Consider the other mathematical types in Python: ints, floats, and complex numbers. None of these have a "zero" class attribute, or a zero constructor, instead they return zero when called with no arguments. So perhaps it might be best to do like so:

class Vector3(object):
    def __init__(self, x=0, y=0, z=0):
        self.x = x
        self.y = y
        self.z = z 

This is less like Unity3D and more like Python, if you know what I mean.

like image 127
Devin Jeanpierre Avatar answered Oct 09 '22 20:10

Devin Jeanpierre