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?
Read-only means that we can access the value of a property but we can't assign any value to it.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With