[转载] Python类中的私有变量和公有变量

参考链接: 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540546.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV探索之路(二十五):制作简易的图像标注小工具

搞图像深度学习的童鞋一定碰过图像数据标注的东西,当我们训练网络时需要训练集数据,但在网上又没有找到自己想要的数据集,这时候就考虑自己制作自己的数据集了,这时就需要对图像进行标注。图像标注是件很枯燥又很费人力物力的一件…

固件的完整形式是什么?

FW:前进 (FW: Forward) FW is an abbreviation of "Forward". FW是“ Forward”的缩写 。 It is an expression, which is commonly used in Gmail or messaging platform. It is also written as FWD or Fwd or Fw. It shows that the email has been s…

[转载] python __slots__ 详解(上篇)

参考链接: Python的__name __(特殊变量) python中的new-style class要求继承Python中的一个内建类型, 一般继承object,也可以继承list或者dict等其他的内建类型。 在python新式类中,可以定义一个变量__slots__,它的作…

委托BegionInvoke和窗体BegionInvoke

委托BegionInvoke是指通过委托方法执行多线程任务,例如: //定义委托成员变量 delegate void dg_DeleAirport(); //指定委托函数 dg_DeleAirport dga AirportBLL.DeleteHistoryTransAirport; //通过BeginInvoke以异步线程方式执行委托函数,可…

图论 弦_混乱的弦

图论 弦Problem statement: 问题陈述: You are provided an input string S and the string "includehelp". You need to figure out all possible subsequences "includehelp" in the string S? Find out the number of ways in which the s…

[转载] Python列表操作

参考链接: Python中的基本运算符 Python列表: 序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推; Python有6个序列的…

「原创」从马云、马化腾、李彦宏的对话,看出三人智慧差在哪里?

在今年中国IT领袖峰会上,马云、马化腾、李彦宏第一次单独合影,同框画面可以说很难得了。BAT关心的走势一直是同行们竞相捕捉的热点,所以三位大Boss在这次大会上关于人工智能的见解,也受到广泛关注与多方解读。马云认为机器比人聪明…

python 注释含注释_Python注释

python 注释含注释Python注释 (Python comments) Comments in Python are used to improve the readability of the code. It is useful information given by the programmer in source code for a better understanding of code and logic that they have used to solve the …

C2的完整形式是什么?

C2:核心2 (C2: Core 2) C2 is an abbreviation of "Core 2" or "Intel Core 2". C2是“ Core 2”或“ Intel Core 2”的缩写 。 It is a family of Intels processor which was launched on the 27th of July, 2006. It comprises a series of…

scala特性_Scala | 特性应用

scala特性特性应用 (Trait App) Scala uses a trait called "App" which is used to convert objects into feasible programs. This conversion is done using the DelayedInit and the objects are inheriting the trait named App will be using this function. T…

[转载] Python3中的表达式运算符

参考链接: Python中的除法运算符 1:Python常用表达式运算符 yield 生成器函数send协议 lambda args:expression 创建匿名函数 x if y else z 三元选择表达式(当y为真时,x才会被计算) x or y 逻辑或(仅但x为假时y才会被计算) x and …

字符串矩阵转换成长字符串_字符串矩阵

字符串矩阵转换成长字符串Description: 描述: In this article, we are going to see how backtracking can be used to solve following problems? 在本文中,我们将看到如何使用回溯来解决以下问题? Problem statement: 问题陈述&#xf…

pythonchallenge_level2

level2 地址:http://www.pythonchallenge.com/pc/def/ocr.html。 源码:gitcode.aliyun.com:qianlizhixing12/PythonChallenge.git。 问题:找出页面源码一点提示注释中的稀有字符。 #!/usr/bin/env python3 # -*- coding:UTF-8 -*-# Level 2im…

[转载] python类运算符的重载

参考链接: Python中的运算符重载 alist input().split() blist input().split() n float(input()) class Vector: def __init__(self, x0, y0, z0): # 请在此编写你的代码(可删除pass语句) self.X x self.Y y self.Z z # 代码结束 def __add__(self, other):…

r语言 运算符_R语言运算符

r语言 运算符R语言中的运算符 (Operators in R Language) Generally speaking, an operator is a symbol that gives proper commands to the compiler regarding a specific action to be executed. The operators are used for carrying out the mathematical or logical cal…

[转载] Python基础之类型转换与算术运算符

参考链接: Python中的运算符函数| 1 一、注释 1.注释:对程序进行标注和说明,增加程序的可读性。程序运行的时候会自动忽略注释。 2.单行注释:使用#的形式。但是#的形式只能注释一行,如果有多行,就不方便…

java awt 按钮响应_Java AWT按钮

java awt 按钮响应The Button class is used to implement a GUI push button. It has a label and generates an event, whenever it is clicked. As mentioned in previous sections, it extends the Component class and implements the Accessible interface. Button类用于…

解决“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题”...

在VS2005下用C写的程序,在一台未安装VS2005的系统上, 用命令行方式运行,提示: “系统无法执行指定的程序” 直接双击运行,提示: “由于应用程序的配置不正确,应用程序未能启动,重新安…