我的Python学习笔记:私有变量
创始人
2024-05-04 02:35:16

一、私有变量的定义

在Python中,有以下几种方式来定义变量:

  • xx:公有变量
  • _xx:单前置下划线,私有化属性或方法,类对象和子类可以访问,from somemodule import *禁止导入
  • __xx:双前置下划线,私有化属性或方法,无法在外部直接访问(名字重整所以访问不到)
  • __xx__:双前后下划线,系统定义名字(不要自己发明这样的名字)
  • xx_:单后置下划线,用于避免与Python关键词的冲突

如以下例子所示,我在test类中定义了num,_num 和 __num三个属性,并创建了test的类对象t,对这三个属性进行访问,__num不能被访问到

class test(object):def __init__(self):self.num = 10self._num = 20self.__num = 30t = test()
print(t.num)    # 10
print(t._num)   # 20
# print(t.__num)  # AttributeError: 'test' object has no attribute 
'__num'

可以使用命令dir查看t中的属性和方法,__num的名字已经被重整为“_test__num”了,可以使用t._test__num对__num进行访问

注:虽然私有变量可以通过_类名__变量名来访问,但强烈建议不要这样做

二、使用不同方法导入模块,模块中私有变量的使用区别

在使用不同方法导入模块后,是否能使用模块中的私有属性和方法,有以下两种情况

  • 在使用 from somemodule import * 导入模块的情况下,不能导入或使用私有属性和方法
  • 在使用 import somemodule 导入模块的情况下,能导入并使用私有属性和方法

首先我们先创建一个test.py文件,将下面代码复制进去:

num = 10
_num = 20
__num = 30def test():print("--test--")def _test2():print("--test2--")def __test3():print("---test3--")
  • 使用 from somemodule import * 进行导入,不能导入私有变量,结果如下:
In [1]: from test import *In [2]: num
Out[2]: 10In [3]: _num
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
 in ()
----> 1 _numNameError: name '_num' is not definedIn [4]: __num
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
 in ()
----> 1 __numNameError: name '__num' is not definedIn [5]: test()
--test--In [6]: _test2()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
 in ()
----> 1 _test2()NameError: name '_test2' is not definedIn [7]: __test3()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
 in ()
----> 1 __test3()NameError: name '__test3' is not defined

  • 使用 import somemodule 进行导入,能导入私有变量,结果如下:
In [8]: import testIn [9]: test.num
Out[9]: 10In [10]: test._num
Out[10]: 20In [11]: test.__num
Out[11]: 30In [12]: test.test()
--test--In [13]: test._test2()
--test2--In [14]: test.__test3()
---test3--

三、对类中的私有属性进行操作的方法

如果你想对类中的私有属性进行操作时,有以下三种方法:

1、getter和setter:

添加getter和setter方法,类对象通过调用这两种方法来对私有属性进行操作

class test(object):def __init__(self):self.__num = 10def getNum(self):return self.__numdef setNum(self, value):self.__num = valuet = test()
print(t.getNum())   # 10
t.setNum(20)
print(t.getNum())   # 20

  2、property方法

class test(object):def __init__(self):self.__num = 10def getNum(self):return self.__numdef setNum(self, value):self.__num = valuenum = property(getNum,setNum)t = test()
print(t.num)   # 10
t.num = 20
print(t.num)   # 20

关于property方法,我们来看下官方文档:

由文档可得:

  • property方法包含四个参数,分别为fget,fset,fdel,doc,分别对应getter方法,setter方法,deleter方法和方法说明
  • property()方法返回一个property属性,如果c是C的实例,那么c.x会调用getter方法,c.x = value会调用setter方法,而del c.x会调用deleter方法

  

  3、@property

class test(object):def __init__(self):self.__num = 10@propertydef num(self):return self.__num@num.setterdef num(self, value):self.__num = valuet = test()
print(t.num)   # 10
t.num = 20
print(t.num)   # 20

关于@property,官方文档如下:

根据文档可得:

  • 我们可以把property()方法当成一个装饰器来使用,使用@property对方法进行装饰
  • 装饰器@property把方法x()转换成了与方法名同名的getter方法,"I'm the 'x' property."是property的doc参数
  • 调用方法和property()方法一样

相关内容

热门资讯

北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...