Prevent creating new attributes outside __init__

前端 未结 11 1510
迷失自我
迷失自我 2020-12-04 07:23

I want to be able to create a class (in Python) that once initialized with __init__, does not accept new attributes, but accepts modifications of existing attri

11条回答
  •  不思量自难忘°
    2020-12-04 07:38

    I like very much the solution that uses a decorator, because it's easy to use it for many classes across a project, with minimum additions for each class. But it doesn't work well with inheritance. So here is my version: It only overrides the __setattr__ function - if the attribute doesn't exist and the caller function is not __init__, it prints an error message.

    import inspect                                                                                                                             
    
    def froze_it(cls):                                                                                                                      
    
        def frozensetattr(self, key, value):                                                                                                   
            if not hasattr(self, key) and inspect.stack()[1][3] != "__init__":                                                                 
                print("Class {} is frozen. Cannot set {} = {}"                                                                                 
                      .format(cls.__name__, key, value))                                                                                       
            else:                                                                                                                              
                self.__dict__[key] = value                                                                                                     
    
        cls.__setattr__ = frozensetattr                                                                                                        
        return cls                                                                                                                             
    
    @froze_it                                                                                                                                  
    class A:                                                                                                                                   
        def __init__(self):                                                                                                                    
            self._a = 0                                                                                                                        
    
    a = A()                                                                                                                                    
    a._a = 1                                                                                                                                   
    a._b = 2 # error
    

提交回复
热议问题