python 中_ 与__ 与__xxxx__的区别

_xx 单下划线开头

Python中没有真正的私有属性或方法,可以在你想声明为私有的方法和属性前加上单下划线,以提示该属性和方法不应在外部调用.如果真的调用了也不会出错,但不符合规范.

 

Python中不存在真正的私有方法。为了实现类似于c++中私有方法,可以在类的方法或属性前加一个“_”单下划线,意味着该方法或属性不应该去调用,它并不属于API。

  1.  
    #!/usr/bin/env python
  2.  
    # coding:utf-8
  3.  
    class Test():
  4.  
        def __init__(self):
  5.  
            pass
  6.  
        def _one_underline(self):  # 定义私有方法,都只能被类中的函数调用,不能在类外单独调用
  7.  
            print("_one_underline")
  8.  
        def __two_underline(self): # 防止类被覆盖,都只能被类中的函数调用,不能在类外单独调用
  9.  
            print("__two_underline")
  10.  
     
  11.  
        def output(self):
  12.  
            self._one_underline()
  13.  
            self.__two_underline()
  14.  
    if __name__ == "__main__":
  15.  
     
  16.  
        obj_test=Test()
  17.  
        obj_test.output()
  18.  
    '''
  19.  
    #输出结果为:
  20.  
    localhost:attempt_underline a6$ python undeline.py
  21.  
    _one_underline
  22.  
    __two_underline
  23.  
    '''

"__XX"双下划线

这个双下划线更会造成更多混乱,但它并不是用来标识一个方法或属性是私有的,真正作用是用来避免子类覆盖其内容。

让我们来看一个例子:

  1.  
    #!/usr/bin/env python
  2.  
    # coding:utf-8
  3.  
    class A(object):
  4.  
        def __method(self):
  5.  
            print("I'm a method in A")
  6.  
        def method(self):
  7.  
            self.__method()
  8.  
            
  9.  
    class B(A):
  10.  
        def __method(self):
  11.  
            print("I'm a method in B")
  12.  
     
  13.  
    if __name__ == "__main__":
  14.  
        a = A()
  15.  
        a.method()
  16.  
        b = B()
  17.  
        b.method()
  18.  
    ‘’‘
  19.  
    # 输出结果为:
  20.  
    localhost:attempt_underline a6$ python undeline.py
  21.  
    I'm a method in A
  22.  
    I'm a method in A
  23.  
    ’‘’

 

我们给A添加一个子类,并重新实现一个__method:

  1.  
    class B(A):
  2.  
    def __method(self):
  3.  
    print("I'm a method in B")
  4.  
     
  5.  
    b = B()
  6.  
    b.method()

#输出结果为:

I'm a method in A

就像我们看到的一样,B.method()不能调用B.__method的方法。实际上,它是"__"两个下划线的功能的正常显示。

因此,在我们创建一个以"__"两个下划线开始的方法时,这意味着这个方法不能被重写,它只允许在该类的内部中使用。

"__xx__"前后各双下划线

当你看到"__this__"的时,就知道不要调用它。为什么?因为它的意思是它是用于Python调用的,如下:

  1.  
    >>> name = "igor"
  2.  
    >>> name.__len__() 4
  3.  
    >>> len(name) 4
  4.  
    >>> number = 10
  5.  
    >>> number.__add__(20) 30
  6.  
    >>> number + 20 30

“__xx__”经常是操作符或本地函数调用的magic methods。在上面的例子中,提供了一种重写类的操作符的功能。

在特殊的情况下,它只是python调用的hook。例如,__init__()函数是当对象被创建初始化时调用的;__new__()是用来创建实例。

  1.  
    class CrazyNumber(object):
  2.  
        def __init__(self, n):
  3.  
            self.n = n
  4.  
        def __add__(self, other): #加法
  5.  
            return self.n - other
  6.  
        def __sub__(self, other): #减法
  7.  
            return self.n + other
  8.  
        def __str__(self):
  9.  
            return str(self.n)
  10.  
     
  11.  
    num = CrazyNumber(10)
  12.  
    print type(num) 输出 <class '__main__.CrazyNumber'>
  13.  
    print num 输出 10
  14.  
    print num + 5 输出 5
  15.  
    print num - 20 输出 30

另外一个例子:

  1.  
    class Room(object):
  2.  
        def __init__(self):
  3.  
            self.people = []
  4.  
     
  5.  
        def add(self, person):
  6.  
            self.people.append(person)
  7.  
            self.people.append(person)
  8.  
     
  9.  
        def __len__(self):
  10.  
            return len(self.people)
  11.  
     
  12.  
     
  13.  
    room = Room()
  14.  
    room.add("Igor")
  15.  
    print len(room)  输出 3

结论

    • 使用_one_underline来表示该方法或属性是私有的,不属于API;
    • 使用__just_to_underlines,来避免子类的重写!
    • 当创建一个用于python调用或一些特殊情况,如子类不能覆盖的那些父类方法时,使用__two_underline__;
posted @ 2019-06-02 19:08  萤huo虫  阅读(1042)  评论(0编辑  收藏  举报