如何在Python类中创建抽象保护字段?

如何在Python类中创建抽象保护字段?,python,python-3.x,metaprogramming,Python,Python 3.x,Metaprogramming,我需要编写十几个类,它们之间的区别只是变量,这对于类的稳定工作是必不可少的。没有这些变量类就不能工作,变量的改变会破坏它们。我编写了一个代码,用于创建相应的元LSS: from abc import ABCMeta, abstractmethod, abstractproperty import re def get_field_protector(*names): def check_attributes(cls): for t in names:

我需要编写十几个类,它们之间的区别只是变量,这对于类的稳定工作是必不可少的。没有这些变量类就不能工作,变量的改变会破坏它们。我编写了一个代码,用于创建相应的元LSS:

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 
在我开始使用以下类之前,它工作正常:

class test(object, metaclass=get_field_protector("essential_field")):
    essential_field="some_value"
    def __init__(self, val):
        self.val=val
当我尝试创建此类类时,我收到:

>>> 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) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“/media/bykov/9016-4EF8/main_architecture.py”,第13行,内部 返回inp_方法(cls、*args、**kwargs) TypeError:对象()不接受任何参数
布鲁诺的评论是正确的。在Python中,您不需要“保护”父类的属性,只需使用两个带前缀的下划线来命名它。在您的示例中,
\u基本\u字段
。这意味着对任何Decedents都不使用它。

永远不要将
键入(self)
(或
self.\uuuu class\uuuuuuu
,这是相同的事情)传递到
超级
!您的问题被标记为
python-3.x
,因此只需使用
super()
。看,你真的需要那么防御性吗???Python是一种动态语言,它更多地依赖于约定和适当的文档,而不是依赖于语言强化的限制,试图与Python的本质作斗争主要是浪费时间。@Brunodesshuilliers,这本不应该是重复的。这并不能解决问题。我不明白你为什么要重写/修饰类的
\uuuu new\uuu
方法。您知道每次创建
test
类的实例时都会调用
\uuuuuuuuuuuuuunew\uuuuuuuuuuu
,对吗?为什么每次创建新实例时都需要调用
check_attributes
?你不能在类创建后再调用一次吗?@Aran Fey也许你是对的。在重新定义新方法的情况下,用户必须执行super()。uuu new_uuu(cls,*args,**kwargs)的目标不是使其“像C#一样受到保护”,而是抛出异常,然后变量偶尔会更改或忘记,并且没有定义。这确实节省了调试时的时间