使用双下划线时何时会发生名称重整?

时间:2018-12-01 05:37:42

标签: python python-3.x class

class Test():

    def __init__(self):
        self.__test = "cats"
        print(self.__test)

    def __example(self):
        print("Hello World")

x = Test()
print(x.__dict__)

使用我上面编写的代码,将显示print语句以访问变量test,我将需要编写_Test__test,但是如图所示,如果我随后直接调用该变量,则可以打印该变量在__init__方法中。因此,我的问题是,如果我在用它的名字self.__test声明它之后可以直接访问它,到那时它就会被篡改?

2 个答案:

答案 0 :(得分:1)

通过.__访问的属性在类主体中的任何地方被修饰(但是内部类声明将首先到达它。)

认为它是句法糖。

Test类主体的上下文中,self.__test是错误名称self._Test__test别名;在上下文中,它们的意思是完全相同的东西

通过演示可以使这一点更加清楚。首先,一些辅助类。

class PrintAttrAccess:
    def __getattr__(self, name):
        print(name)

class Empty: pass

现在进行演示:

class Test:
    print('IN TEST BODY')
    (lambda: PrintAttrAccess().__in_lambda)()  # Anywhere in the class body works.
    classfoo = Empty()
    classfoo.__foo = 'foo'
    print("Same thing?", classfoo.__foo is classfoo._Test__foo)
    print("vars() of classfoo:", vars(classfoo))

    class Inner:
        print('IN INNER')
        PrintAccess().__inner

    def __init__(self):
        print('IN INIT')
        print("Who am I?", self)
        self.__test = "cats"
        print(self._Test__test)  # It's ALREADY MANGLED!
        # This line means exactly the same as the one above.
        print(self.__test)
        localfoo = Empty()
        localfoo.__spam = 'spam' # "self" isn't special.
        print("vars() of localfoo:", vars(localfoo))


def outside_method(self):
    print('OUTSIDE BODY')
    print("Who am I?", self)
    self.__test = "dogs"
    print(self._Test__test)
    print(self.__test)  # Sugar doesn't apply outside of class body.

Test.outside_method = outside_method  # Add a new method to Test class.

Test().outside_method()  # init and call as method.

输出为:

IN TEST BODY
_Test__in_lambda
Same thing? True
vars() of classfoo: {'_Test__foo': 'foo'}
IN INNER
_Inner__inner
IN INIT
Who am I? <__main__.Test object at 0x000001CCF3048978>
cats
cats
vars() of localfoo: {'_Test__spam': 'spam'}
OUTSIDE BODY
Who am I? <__main__.Test object at 0x000001CCF3048978>
cats
dogs

答案 1 :(得分:0)

  

如果我在用它的名字self.__test声明它之后可以直接访问它,到那时它会被篡改?

当您从课程的外部引用它时,它就会变得混乱。

您的第5行print(self.__test)没有被弄乱,因为您是在类的内部中引用它的。仅当您从班级外部引用它时,它才会被破坏。因此,您将致电

print(x._Test__test)

请注意,您也可以在课程中使用self._Test__test

class Test():
    def __init__(self):
        self.__test = "cats"

    def get(self):
        return self._Test__test

x = Test()
print(x.get())                      ##  cats

我认为本文对此进行了很好的解释:The Meaning of Underscores in Python