Python 如何限制对未定义的类/实例变量的访问?

Python 如何限制对未定义的类/实例变量的访问?,python,python-3.x,oop,Python,Python 3.x,Oop,Python允许访问未定义的类/实例变量 我定义了一个简单/空的python类,如下所示。现在,如果我使用实例变量或类名为未定义变量设置值,Python允许我自由地为未定义变量设置值,还允许我像访问实例或类变量一样访问它,而不会抛出任何错误。因此,在一个简单的例子中,我能够设置未定义的实例和类变量,而不会出现任何问题 如何限制用户在Python中设置未定义的实例和类变量 这里,Python如何处理这些未定义的变量(undefined_variable_1和undefined_variable_2

Python允许访问未定义的类/实例变量

我定义了一个简单/空的python类,如下所示。现在,如果我使用实例变量或类名为未定义变量设置值,Python允许我自由地为未定义变量设置值,还允许我像访问实例或类变量一样访问它,而不会抛出任何错误。因此,在一个简单的例子中,我能够设置未定义的实例和类变量,而不会出现任何问题

  • 如何限制用户在Python中设置未定义的实例和类变量

  • 这里,Python如何处理这些未定义的变量(
    undefined_variable_1
    undefined_variable_2
    )?这些被视为实例变量、类变量还是其他变量


  • 我们如何限制用户设置/访问未定义的实例/实例变量?

    为此,您可以设置
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>以约束类实例可以具有的属性:

    class Restricted:
    
        __slots__ = ('a', 'b')
    
    r = Restricted()
    r.a = 1  # okay
    r.b = 2  # okay
    r.c = 3  # error
    
    如果希望类对象具有相同的功能,可以创建自定义元类并重写
    \uuuu setattr\uuuu

    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
    

    你能退一步解释一下你为什么要这么做吗?它有什么问题?这就是它在Python中的工作方式。变量,而不是本例中的属性,在分配给之前不存在them@juanpa.arrivillaga我怀疑他们真正想要的是阻止类外的代码创建新属性。@juanpa.arrivillaga-即使我通过uuu init_uuu()初始化其他实例属性,行为也是一样的方法并设置未定义的变量,如我的示例中所示。如果Python允许我们使用自定义类的未定义属性,那么它如何支持封装?请澄清。@VivekN Python建立在我们都是同意的成年人这一理念之上。你不会阻止人们做潜在的可怕的事情;你告诉他们你的类要处理的情况,如果他们想探究它的内部,并可能造成混乱,那就由他们来决定。甚至我在回答中提到的
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    方法,其主要目标都是节省内存。@VivekN是的,我在回答中提到了这。为此,您需要一个自定义元类,我提供了一个示例。
    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