Python类中的私有变量和公有变量

我们这里就直奔主题,不做基础铺垫,默认你有一些Python类的基础,大家在看这篇博客的时候,如果基础知识忘了,可以去菜鸟教程

从一个简单的类开始

class A():       #定义一个类 A
    a     = 100  #公有变量
    _b    = 200  #公有变量
    __c   = 300  #私有变量
    __d__ = 400  #公有变量
a = A()     #实例化一个对象a,当然可以取另外一个名字b
print(a.a,a._b,a.__c,a.__d__)   #打印四个变量的值

运行结果:
Traceback (most recent call last):
File “c:\users\12090\desktop\a.py”, line 7, in
print(a.a,a._b,a.__c,a.d)
AttributeError: ‘A’ object has no attribute ‘__c’

运行结果,提示__c不能访问,这里的错误信息,并没有指出__c是私有变量,在类外不能访问
我们程序这样改动
在这里插入图片描述

通过成员函数间接访问私有变量

在这里插入图片描述

a=A,和a=A()的区别

我们把第8行改造一下:
去掉括号,就像这样:
在这里插入图片描述

a = A会成功生成对象a,而且通过对象a可以正确访问到公有变量a,_b,d。但是在调用函数print_c()的时候,出问题,错误提示
TypeError: print_c() missing 1 required positional argument: ‘self’
提示缺少参数,怎么解决这个问题呢:
显示传递一个类,或者对象进去
在这里插入图片描述
那么a=A,和a=A()有什么区别呢?
区别是:
如果是a=A,则不会调用类中的构造函数;
如果是a=A(),则会调用构造函数;

A()会调用构造函数

我们来做一个实验,
python中的构造函数名是系统规定的,init,添加后如下:

class A():       #定义一个类 A
    a     = 100  #公有变量
    _b    = 200  #公有变量
    __c   = 300  #私有变量
    __d__ = 400  #公有变量
    def __init__(self):   #构造函数定义
        print('calling __init__....')
    def print_c(self):  #通过成员函数访问私有变量
        return self.__c
a = A          #不会调用构造函数
print(a.a,a._b,a.print_c(a),a.__d__)
b = A()        #会调用构造函数   
print(b.a,b._b,b.print_c(),b.__d__)

运行结果:
在这里插入图片描述
当我们通过A()这种形式构造对象的时候,会显示调用构造函数__init__。
当我们通过A这种形式构造对象的时候,不会调用构造函数。

构造函数,构造了什么

“构造”这个词,是一个动词,就是要造一个东西,那么造什么呢,其实我们上面的例子,可能让初学者有点不明所以,所以接下来,我们让构造函数做点有意义的事情,程序如下:

class A():       #定义一个类 A
    a     = 100  #公有变量
    _b    = 200  #公有变量
    __c   = 300  #私有变量
    __d__ = 400  #公有变量
    def __init__(self,a,b,c,d):   #通过构造函数给公有变量或者私有变量重新赋值
        print('构造前:',self.a,self._b,self.__c,self.__d__)
        self.a = a
        self._b = b
        self.__c = c
        self.__d__ = d
        print('构造后:',self.a,self._b,self.__c,self.__d__)
    def print_c(self):  #通过成员函数访问私有变量
        return self.__c
a = A(1000,2000,3000,4000)          #通过传值构造对象

运行结果:
在这里插入图片描述
这个例子,就证明了构造函数的作用

python中 self的作用

self这个单词是自己,自我的意思,它代表对象本身,其实你可以换一个单词也可以,比如you
在这里插入图片描述

照样可以运行
甚至一个地方用self,一个地方用you也可以
在这里插入图片描述

self的实际意义

我们一般使用self,python系统也默认是self,但是self的作用远不止单词意思这么简单
比如我们去掉self
在这里插入图片描述

运行起来,好像也没问题,但是这里的a,_b,__c,d(构造函数里面),并不是公有变量中的a,_b,__c,d。怎么见得呢?
我们把第七行打开
在这里插入图片描述
运行结果出错:
Traceback (most recent call last):
File “c:\users\12090\desktop\a.py”, line 13, in
a = A(1000,2000,3000,4000) #调用构造函数
File “c:\users\12090\desktop\a.py”, line 7, in init
print(‘构造前:’,a,_b,__c,d)
UnboundLocalError: local variable ‘_b’ referenced before assignment

错误原因,是本地变量_b没有引用,这个local是本地的意思,也就是在构造函数__init__函数作用范围内。那么第7行的a为什么没有报错呢,因为a用的是参数里面的a,并不是公有变量中a。
所以,第12行的打印结果,其实打印的是局部变量,也就是说,在构造函数里面我们定义了一套与公有变量同名的变量,在这种情况下,局部变量优先。
所以,self其实非常有作用,必须通过self来显示指定公有变量,不然会当作局部变量。
我们还可以进一步说明这个问题

进一步证明

在这里插入图片描述

结论

Python类中公有变量和私有变量定义一般定义在类名下面,构造函数上面,比如这样:
class A:
公有变量
私有变量
def init():
。。。
其中私有变量需要有前缀下划线__
如果成员函数(包括构造函数),中出现了与公有变量(私有变量)同名的变量,则python系统会屏蔽公有变量和私有变量,把改变量当成局部变量。如果要在成员函数(包括构造函数)使用公有变量和私有变量,必须通过self显示指定,就像这样:
class A:
a = 100
_b = 200
__c = 300
def init(self,a,b,c):
self.a = a #使用公有变量a
_b = b #屏蔽了公有变量_b,重新定义了一个局部变量_b
self.__c =c #使用私有变量__c

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下家山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值