当使用双下划线时,什么时候会出现名称损坏?

2024-03-28 18:58:45 发布

您现在位置:Python中文网/ 问答频道 /正文

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之后直接访问它,它在哪一点上会被损坏?你知道吗


Tags: 方法代码testselfhelloworldinitexample
2条回答

If I can access it directly after it has been declared by its name i.e self.__test, at which point does it become mangled?

当您从类外部引用它时,它会损坏。你知道吗

您的第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。你知道吗

通过.__访问的属性在类主体的任何地方都会被损坏(但是内部类声明会首先到达它)。你知道吗

把它想象成句法上的糖。

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

相关问题 更多 >