python中的_xx, __xx, __xx__

一、从模块分析

########  bb.py (一个用来导入的模块) ##########

var = 0
_var = 1
__var = 2
__var__ = 3

 

1. from module import *

########### aa.py ###########

from bb import *

print var       #ok

print _var

print __var

print __var__

 

$python aa.py

只有print var可以正确执行,其它都会报NameError: "xxx" not defined,

即,只要模块成员名之前有一条,两条下划线,都不能通过from module import * 语句导入当前模块中

 

2. from module import xx,

########### aa.py ###########

from bb import var, _var, __var, __var__

print var

print _var

print __var      

print __var__

 

$python aa.py

此时,四条print语句都可以正常执行,可见,通过 import 某个模块中的具体成员,可以消除模块成员的私有性,使得私有成员也可以在当前模块中可见

 

3. import module

########### aa.py ###########

import bb

print bb.var

print bb._var

print bb.__var      

print bb.__var__

 

$python aa.py

此时,四条print语句都可以正常执行,可见,通过导入模块名,然后利用模块名加句点操作符的方式,也可以访问被导入模块的私有成员

 

二、从python类的角度分析

__xx__ 一般是类中的特殊成员,另有他用,我们编写代码的时候,最好不要以这样的方式命名函数,或者变量

############ classtest.py (用来分析类成员的可见性)###############

class Father(object):

  s = 0

  _s = 1

  __s = 2 

  def __init__(self):

    self.a = 0

    self._a = 1

    self.__a = 2

    self.__a__ = 3

  def __getA__(self):

    return self.__a__

 

class Child(Father):

  def __init__(self):

    super(Child, self).__init__()

 

程序段一:测试类成员对于类对象的可见性

father = Father()

print father.a        #ok

print father._a      #ok,但是在C++中是不能这样访问的

print father.__a    #error

__a相当于类Father的私有成员,_a相当于类Father的受保护成员(我在很多论坛里都有看到有这种说法,即,单下划线开头的类成员是受保护的),

通过和C++的比较,受保护的类成员,在C++中是没法通过类对象直接用句点操作符来引用的,python的受保护,没有C++那么严格

 

程序段二:测试父类私有成员对子类对象的可见性

child = Child()

print child.a            #ok

print child._a          #ok,同样的,在C++中是不可访问的

print child.__a        #error

 

程序段三:测试类的静态成员可见性

father = Father()

print father.s          #ok

print father._s        #ok

print father.__s      #error

print Father.s        #ok

print Father._s      #ok

print Father.__s    #error

 

程序段四:测试类的静态成员在子类中的可见性

child =Child()

print child.s        #ok

print child._s      #ok

print child.__s    #error

print Child.s       #ok

print Child._s     #ok

print Child.__s   #error

 

程序段五:终极测试,深度破坏类成员私密性

如果想访问类的__xx这样的私有成员,可以有如下变态的方法,不过这种方法最好不要用在实际开发中

例如上面的Father类,有一个私有成员__a,可以通过加上_Father前缀,使得类对象可以通过句点操作符直接访问

father = Father()

print father._Father__a   #ok

father._Father__a = 3    #ok

child = Child()

print child._Father__a    #ok

print child._Child__a      #error,__a是继承自Father类,因此,不能这样访问

 

程序段六:补充测试,测试类中以双下划线开头,以双下划线结尾的特殊类成员

father = Father()

print father.__a__    #ok

print father.__getA__()  #ok

__a__数据成员,__getA__()成员函数,它们都是双下划线开头,双下划线结尾,这样的命名方式,代表它们是类的特殊成员,一般情况下定制类的时候,可以实现__xx__()这样的特殊函数

 

转载于:https://www.cnblogs.com/qiang-upc/p/11143501.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值