Vivek.N
Vivek.N

Reputation: 217

How to restrict the access to undefined class/instance variable?

Python allowing access to undefined class/instance variable

I have defined a simple/empty python class as below. Now if I set a value for an undefined variable either with an instance variable or with class name, Python freely allows me to set the value for undefined variable and also allows me to access it like a instance or class variable without throwing any error. So in a nut shell, I am able to set undefined instance & class variables without any issues.

  1. How do we restrict users from setting undefined instance and class variables in Python.

  2. Here, how does Python treat these undefined variables (undefined_variable_1 and undefined_variable_2)? Are these treated as instance variable or class variable or something else?

class Test:

  pass

### #Now instantiate the class and try setting & it accessing undefined variables
t1 = Test()

t1.undefined_variable_1 = "Undefined class/instance variable being set through instance variable (t1)"

### #Access the undefined variable through instance variable
print(t1.undefined_variable_1) 

Test.undefined_variable_2 = "Undefined class/instance variable being set through Class name (Test)"

### #Access the undefined variable through Class name
print(Test.undefined_variable_2) 

How do we restrict user from setting/accessing undefined instance/instance variable?

Upvotes: 2

Views: 538

Answers (1)

gmds
gmds

Reputation: 19885

For this purpose, you can set __slots__, which constrains the attributes that an instance of a class can have:

class Restricted:

    __slots__ = ('a', 'b')

r = Restricted()
r.a = 1  # okay
r.b = 2  # okay
r.c = 3  # error

If you want to have the same functionality for the class object, you can create a custom metaclass and override __setattr__:

class RestrictedMeta(type):

    def __setattr__(self, attr, value):
        if attr in ('a', 'b'):
            super().__setattr__(attr, value)

        else:
            raise TypeError(f"Can't assign to attribute '{attr}' of class 'Restricted'")

class Restricted(metaclass=RestrictedMeta):
    pass

Restricted.a = 1  # okay
Restricted.b = 2  # okay
Restricted.c = 3  # error

Upvotes: 4

Related Questions