How to make abstract protected fields in Python class?

Viewed 306

I need to write dozen of class which differ each other only by variables, which are essential for stable work of class. Classes can not work without such variables and changing of variables can broke them. I have wriiten a code for creating a corresponding metaclss:

from abc import ABCMeta, abstractmethod, abstractproperty
import re

def get_field_protector(*names):
    def check_attributes(cls):
        for t in names:
            if not hasattr(cls, t):
                raise Exception('Abstract field "{0}" have to be defined'.format(t))
    def decorate_new_method(inp_method, class_name):
        def inner(cls, *args, **kwargs):
            if cls.__new__.decorated==class_name:
                check_attributes(cls)
            return inp_method(cls, *args, **kwargs)
        return inner
    class result_protector(ABCMeta):
        def __setattr__(self, name, value):
            if name in names:
                raise Exception("Read only class attribute!")
            super(self.__class__, self).__setattr__(name, value)
        def __delattr__(self, name):
            if name in names:
                raise Exception("Read only class attribute!")
            super(self.__class__, self).__delattr__(name)
        def __init__(self, name, bases, attributes):
            super(self.__class__, self).__init__(name, bases, attributes)
            if not hasattr(self.__new__, 'decorated'):
                self.__new__=decorate_new_method(self.__new__, name)
                self.__new__.decorated=name
    return result_protector 

It was work fine until I dstart use classes like:

class test(object, metaclass=get_field_protector("essential_field")):
    essential_field="some_value"
    def __init__(self, val):
        self.val=val

When I try to create such class, I receive:

>>> test(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/media/bykov/9016-4EF8/main_architecture.py", line 13, in inner
    return inp_method(cls, *args, **kwargs)
TypeError: object() takes no parameters
1 Answers

Bruno's comment is correct. In Python, you don't "protect" a property of a parent class, you simply name it with two prefixed underlines. In your example __essential_field. That means to leave it alone for any decendents.

Related