Python中下划线在变量名和方法名中的含义

单下划线和双下划线在Python变量名和方法名中的含义,有些仅仅是作为约定,用于提示开发人员;而另一些则对Python解释器有特殊含义。

python中的下划线主要分为如下几类:

  1. 前置单下划线

    • _var,主要是用于将变量或方法定义为私有属性。它对于程序员而言是一种提示,非如java中的私有,而是一种约定俗成,强行访问仍旧可以正常访问。
    class Test:
    	def __init__(self):
    		self.foo = 11
    		self._bar = 23
    # 实例化这个类并尝试访问在__init__构造函数中定义的foo和_bar属性,答案是可以访问,但是不建议访问
    t = Test()
    print(t.foo) #输出:11
    print(t._bar) #输出:23
    

    可以看到,_bar前面的单下划线并没有阻止我们“进入”这个类访问变量的值。
    这是因为Python中的前置单下划线只是一个公认的约定,至少在涉及变量名和方法名时是这样的。但前置下划线会影响从模块中导入名称的方式。

  2. 后置单下划线
    有时,某个变量最合适的名称已被Python语言中的关键词占用。因此,诸如class或def的名称不能用作Python中的变量名。在这样情况下,可以追加一个下划线来绕过命名冲突:

    def make_object(name, class_):
    pass
    

    用一个后置单下划线来避免与Python关键字的命名冲突是一个约定。

  3. 前置双下划线
    以双下划线开头的Python类属性(变量和方法)不是约定的意义,双下划线前缀会让Python解释器重写属性名称,以避免类中的命名冲突,这也称为名称改写(name mangling)

    class Test:
    	def __init__(self):
    	self.foo = 11
    	self._bar = 23
    	self.__baz = 42
    # 实例化这个类并用内置的dir()函数来看看这个对象的属性:
    t = Test()
    print(dir(t))
    print(t._Test__baz)  # 在外部访问__baz变量时,应使用_类名__变量名即_Test__baz
    
    # 输出:
    ['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_bar', 'foo']
    

    现在,看一看这个带有对象属性的列表,并留意原始变量名foo、bar和 bazi有何差异:

    self.foo变量没有改动,在属性列表中显示为foo。

    self._bar也一样,在类中显示为_bar。前面说了,在这种情况下前置下划线仅仅是一个约定,是对程序员的一个提示。

    对于self.__baz,在该列表中找不到__baz这个变量。仔细观察就会看到,这个对象上有一个名为_Test__baz的属性。这是Python解释器应用名称改写之后的名称,是为了防止子类覆盖这些变量。

    对于前置双下划线的变量,在外部访问该变量名时,应使用 _类名__变量名;直接访问__变量名是不存在的。

    用双下划线修饰方法亦如此——名称改写也适用于方法名。

    用双下划线修饰属性或者方法,会出发名称修饰,即在外部访问时,该方法名或变量名会变为_类名__变量名;直接访问__变量名是不存在的。

  4. 前后都有双下划线
    由双下划线包围的变量,则不会发生名称改写,由上下划线包围的方法通常被称为魔法方法(特殊方法)。
    前后由双下划线包围的变量不受Python解释器的影响:

    class B:
    	def __init__(self):
    	self.__private__ = 10
    t = B()
    print(t.__private__)  # 输出:10
    

    就命名约定而言,最好避免在自己的程序重使用双下划线开头和结尾的名称,因为Python语言用于定义的特殊方法。

  5. 单下划线本身
    _在Python REPLs如IDLE Shell中是一个特殊变量(可以表示一个临时值),它表示解释器计算的最后一个表达式的结果
    例子:

    >>>list()
    []
    >>>_.append(10)
    >>>_.append(20)
    >>>_
    [10, 20]
    >>>10 + 5
    15
    >>>[_ for _ in range(10)]
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 0]
    

参考:https://blog.csdn.net/cnds123/article/details/118707525

posted @ 2022-05-19 08:07  EconCoder  阅读(41)  评论(0)    收藏  举报