Home > Enterprise >  How to prevent re-assignment of a class method outside the class?
How to prevent re-assignment of a class method outside the class?

Time:01-28

I want some of my class methods to be not re-assignable outside (or both outside and inside) of the class. A's functions are objects too in python, is it possible to accomplish what I want? Here is the method;

def x(self):
    """Return x, the horizontal distance between the shape and the leftmost
    of the screen, in pixels.
    """
    return self.__x

Now outside of the class, it is easy to mess with this method;

shape = Shape(10, 20)
shape.x = 30
print(shape.x)  # Prints 30
print(shape.x())  # TypeError: 'int' object is not callable

Is it possible to prevent this kind of assignment of class methods?

CodePudding user response:

You could override the __setattr__ method to check to see if the key is in a forbidden list for example...

class Shape:
    def __init__(self, a, b):
        self.__x = a
        self.__y = b

    def x(self):
        return self.__x

    def __setattr__(self, key, value):
        if key in ('x', 'y'):
            raise TypeError(f"You can't change {key}")
        super(Shape, self).__setattr__(key, value)


shape = Shape(11, 20)
shape.z = 100  # OK
print(shape.z)
print(shape.x())
shape.x = 30  # raise an exception

note: As @Chepner noted, Overriding __setattr__ just prevents you from changing the value of x via an assignment statement, not from changing it at all. like object.__setattr__(shape, 'x', 30)

CodePudding user response:

Make x a property with no setter, not a method.

class Shape:
    ...

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

Attempts to assign to x will result in an exception:

>>> shape.x = 30
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

If you really want something that must be called, have the property return that instead of the value the function will return.

class Shape:

    @property
    def x(self):
        return lambda: self.__x
  •  Tags:  
  • Related