您当前的位置: 首页 > 

单下划线与双下划线的区别

发布时间:2019-01-17 12:13:00 ,浏览量:0

单下划线与双下划线的区别
内容目录

单下划线与双下划线的区别单下划线(_)名称前的单下划线(如:_name)名称前的双下划线(如:__name)名称前后的双下划线(如:_ init _)总结

单下划线与双下划线的区别

Python用下划线作为前缀和后缀指定特殊变量和定义方法,主要有如下四种形式:

  • 单下划线(_)
  • 名称前的单下划线(如:_name)
  • 名称前的双下划线(如:__name)
  • 名称前后的双下划线(如:_ init _)
单下划线(_)

只有单划线的情况,主要有两种使用场景:

1、在交互式解释器中,单下划线“_”代表的是上一条执行语句的结果。如果单下划线前面没有语句执行,交互式解释器将会报单下划线没有定义的错误。也可以对单下划线进行赋值操作,这时单下划线代表赋值的结果。但是一般不建议对单下划线进行赋值操作,因为单下划线内建标识符。

 1>>> _  2Traceback (most recent call last):  3  File "", line 1, in  4    _  5NameError: name '_' is not defined  6>>> "python"  7'python'  8>>> _  9'python' 10>>> _="Java" 11>>> _ 12'Java' 13>>> 

2、单下划线“_”还可以作为特殊的临时变量。如果一个变量在后面不会再用到,并且不想给这个变量定义名称,这时就可以用单下划线作为临时性的变量。比如对for循环语句遍历的结果元素并不感兴趣,此时就可以用单下划线表示。

1# _ 这个变量在后面不会用到 2for _ in range(5): 3    print("Python")
名称前的单下划线(如:_name)

当在属性和方法前面加上单下划线“_”,用于指定属性和方法是“私有”的。但是Python不像Java一样具有私有属性、方法、类,在属性和方法之前加单下划线,只是代表该属性、方法、类只能在内部使用,是API中非公开的部分。如果用from import * 和 from import * 时,这些属性、方法、类将不被导入。

 1# Test.py 文件  2  3#普通属性  4value="Java"  5  6#单下划线属性  7_otherValue="Python"  8  9 10#普通方法 11def  method(): 12    print("我是普通方法") 13 14#单下划线方法 15def _otherMethod(): 16    print("我是单下划线方法") 17 18#普通类 19class PClass(object): 20 21    def __init__(self): 22        print("普通类的初始化") 23 24#单下划线类 25class _WClass(object): 26 27    def __init__(self): 28        print("单下划线类的初始化")

将上述的Test.py文件导入,进行测试。

 1>>> from Test import *  2>>> value  3'Java'  4>>> _otherValue  5Traceback (most recent call last):  6  File "", line 1, in  7    _otherValue  8NameError: name '_otherValue' is not defined  9>>> method() 10我是普通方法 11>>> _otherMethod() 12Traceback (most recent call last): 13  File "", line 1, in 14    _otherMethod() 15NameError: name '_otherMethod' is not defined 16>>> p=PClass() 17普通类的初始化 18>>> w=_WClass() 19Traceback (most recent call last): 20  File "", line 1, in 21    w=_WClass() 22NameError: name '_WClass' is not defined

从上面的结果可以看出,不管是属性、方法和类,只要名称前面加了单下划线,都不能导出。

如果对程序进行修改,将在开头加入_ all _,结果会是如何?

 1# Test.py 文件  2  3#将普通属性、单下划线的属性、方法、和类加入__all__列表  4__all__=["value","_otherValue","_otherMethod","_WClass"]  5  6#普通属性  7value="Java"  8  9#单下划线属性 10_otherValue="Python" 11 12#普通方法 13def  method(): 14    print("我是普通方法") 15 16#单下划线方法 17def _otherMethod(): 18    print("我是单下划线方法") 19 20#普通类 21class PClass(object): 22 23    def __init__(self): 24        print("普通类的初始化") 25 26#单下划线类 27class _WClass(object): 28 29    def __init__(self): 30        print("单下划线类的初始化")

将上述修改过的Test.py文件导入,进行测试。

 1>>> from Test import *  2>>> value  3'Java'  4>>> _otherValue  5'Python'  6>>> method()  7Traceback (most recent call last):  8  File "", line 1, in  9    method() 10NameError: name 'method' is not defined 11>>> _otherMethod() 12我是单下划线方法 13>>> p=PClass() 14Traceback (most recent call last): 15  File "", line 1, in 16    p=PClass() 17NameError: name 'PClass' is not defined 18>>> w= _WClass() 19单下划线类的初始化

_ all _是一个字符串列表,不管是普通的还是单下划线的属性、方法和类,都将导出来,使用其他不在这个字符列表上的属性、方法和类,都会报未定义的错误。

不管是属性、方法和类,只要名称前面加了单下划线,都不能导入。除非是模块或包中的“_ all_”列表显式地包含了它们。

名称前的双下划线(如:__name)

我们先看看下面的程序:

 1class Method(object):  2    # 构造器方法  3    def __init__(self, name):  4        # 双下划线属性  5        self.__name = name  6    # 普通方法  7    def sayhello(self):  8        print("Method say hello!")  9    # 双下划线方法 10    def __sayhi(self): 11        print("Method say hi!") 12 13# 初始化Method 14m = Method("Python") 15# 调用sayhello方法 16m.sayhello() 17# 调用sayhi方法 18m.__sayhi() 19# 输出属性__name 20print(m.__name)

上面的程序定义了一个类,这个类有三个方法,一个构造器方法,一个普通方法,一个双下划线方法,以及包括一个双下划线的属性。上面的结果输出的是什么?很多读者可能认为输出的结果如下:

1Method say hello! 2Method say hi! 3Python

那么恭喜你,上面的输出结果是错误的,实际输出的结果为:

1Method say hello! 2Traceback (most recent call last): 3  File "", line 18, in 4AttributeError: 'Method' object has no attribute '__sayhi' 

实际上,当对象调用__sayhi()方法时,将会报Method类没有这个方法属性的错误。那如何去调用以双下划线开头的方法和属性?Python这样设计的目的是什么?

首先回答第一个问题,读者看完下面的程序就知道怎么调用了。

 1class Method(object):  2  3    def __init__(self, name):  4        self.__name = name  5  6    def sayhello(self):  7        print("Method say hello!")  8  9    def __sayhi(self): 10        print("Method say hi!") 11 12 13# 初始化Method 14m = Method("Python") 15# 调用sayhello方法 16m.sayhello() 17# 调用sayhi方法 18#m.__sayhi() 19m._Method__sayhi() 20# 输出属性__name 21#print(m.__name) 22print(m._Method__name)

输出结果如下:

1Method say hello! 2Method say hi! 3Python

我们从上面的程序中可以很清楚的看到,如果要调用以双下划线开头的方法和属性,只要以“类名_方法(属性)”的形式就可以实现方法或者属性的访问了。类前面是单下划线,类名后面是双下划线,然后再加上方法或者属性。但是并不建议调用,因为这是Python内部进行调用的形式。

回答完第一个问题,我们看看第二个问题,Python这样设计的目的是什么?

有很多人认为,Python以双下划线开头的方法和属性表示私有的方法和属性,实际上这样的理解不太准确,也不能说完全错误的。但是这并不是Python设计的目的和初衷,我们先看看下面一段程序和程序运行结果:

 1class AMethod(object):  2  3    def __method(self):  4        print("__method in class Amethod!")  5  6    def method(self):  7        self.__method()  8        print("anthod method in class AMethod!")  9 10class BMethod(AMethod): 11 12    def __method(self): 13        print("__method in class Bmethod!") 14 15 16if __name__=="__main__": 17 18    print("调用AMethod的method方法") 19    a = AMethod() 20    a.method() 21 22    print("调用BMethod的method方法") 23    b = BMethod() 24    b.method()

上面的程序定义了两个类,一个是AMethod类,另外一个是继承了AMethod类的BMethod类。在AMethod类中,定义了两个方法,一个是以双下划线开头的__method方法,另外一个是普通方法。在BMethod类中,重写了AMethod类中的__method方法。

程序运行结果:

1调用AMethod的method方法 2__method in class Amethod! 3anthod method in class AMethod! 4调用BMethod的method方法 5__method in class Amethod! 6anthod method in class AMethod! 7 

运行结果并不是我们想要的结果,b.method()并没有调用BMethod类的__method方法,而这个设计的实际目的是为了避免父类的方法被子类轻易的覆盖。

名称前后的双下划线(如:_ init _)

在Python类中,我们可以常常看到类似于“_ init _ ”的方法,这表示在Python内部调用的方法,一般不建议在程序中调用。比如,当调用len()方法时,实际上调用了 Python中内部的 _ len _ 方法,虽然不建议调用这种以双下划线开头以及结尾的方法,但是可以对这些方法进行重写。比如下面的例子:

 1class Number(object):  2  3    def __init__(self, number):  4        self.number = number  5  6    def __add__(self, number):  7        # 重写方法,返回两个数的差值  8        return self.number - number  9 10    def __sub__(self, number): 11        # 重写方法,返回两个数的和 12        return self.number + number 13 14    def __str__(self): 15        # 重写方法,返回字符串 16        return str(self.number) 17 18 19num = Number(100) 20print(num) # 100 调用了__str__方法 21print(num+50) # 50 + 调用了__add__方法 22print(num-20) # 120 -调用了__sub__方法 

相信看了上面所有对Python中下划线作用的讲解,完全能够理解上述四种下划线所表示的意义。最后将对上面的,进行总结。

总结
  • 单下划线(_): 在交互解释器中,表示上一条语句执行输出的结果。另外,单下划线还可以作为特殊的临时变量,表示在后面将不会在用到这个变量。

  • 名称前的单下划线:只能在内部使用,是API中非公开的部分,不能被 import * 和 from import *导入程序中,除非在all列表中包含了以单下划线开头的属性、方法以及类。

  • 名称前的双下划线:以双下划线开头的属性、方法表示避免父类的属性和方法被子类轻易的覆盖,一般不建议这样定义属性和方法,除非你自己将要做什么。

  • 名称前后的双下划线:这类方法是Python内部定义的方法,你可以重写这些方法,这样Python就可以调用这个重写的方法以及利用操作符。

About Me

........................................................................................................................

● 本文作者:小麦苗,部分内容整理自网络,若有侵权请联系小麦苗删除

● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人weixin公众号(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162

● 本文博客园地址:http://www.cnblogs.com/lhrbest

● 本文pdf版、个人简介及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/

● 数据库笔试面试题库及解答:http://blog.itpub.net/26736162/viewspace-2134706/

● DBA宝典今日头条号地址:http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826

........................................................................................................................

● QQ群号:230161599(满)、618766405

● weixin群:可加我weixin,我拉大家进群,非诚勿扰

● 联系我请加QQ好友(646634621),注明添加缘由

● 于 2019-01-01 06:00 ~ 2019-01-31 24:00 在魔都完成

● 最新修改时间:2019-01-01 06:00 ~ 2019-01-31 24:00

● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

● 版权所有,欢迎分享本文,转载请保留出处

........................................................................................................................

● 小麦苗的微店:https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

● 小麦苗出版的数据库类丛书:http://blog.itpub.net/26736162/viewspace-2142121/

● 小麦苗OCP、OCM、高可用网络班:http://blog.itpub.net/26736162/viewspace-2148098/

● 小麦苗腾讯课堂主页:https://lhr.ke.qq.com/

........................................................................................................................

使用weixin客户端扫描下面的二维码来关注小麦苗的weixin公众号(xiaomaimiaolhr)及QQ群(DBA宝典)、添加小麦苗weixin,学习最实用的数据库技术。

........................................................................................................................

欢迎与我联系

posted @ 2019-01-17 12:13 ^_^小麦苗^_^ 阅读( ...) 评论( ...) 编辑 收藏
关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    108697博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0494s