首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

你们对Python的类访问控制可能一无所知

在Python类中,有属性和方法。外部代码可以直接通过实例来访问修改。

如果需要让内部的属性不被外部访问到,在属性变量前面加上2个下划线:“__”。

在python中,实例的变量名如果是由2个下划线开头的,就代表这是一个私有变量:只有内部可以访问,外部不许直接通过类或者实例访问。

classF:

__name ="xurui"

f = F()

f.__name

F.__name

# 报错

AttributeError: type object'F'hasnoattribute'__name'

虽然说外部访问不了一个内部私有属性,但是可以通过类中方法间接的访问、修改。比如类内部方法get_name和set_name:

classF:

__name ="xurui"

defget_name(self):

returnself.__name,self

defset_name(self,name):

self.__name = name

returnself.__name,self

f = F()# 类中self,都是f这实例对象.

res = f.getName()

print(res,f)

result = f.setName("zhangsan")

print(result,f)

结果:

('xurui', )

('zhangsan', )

双下划线开头的私有属性,是不是一定不能从外部访问呢?

其实不是的:

python中2个有趣的现象,外部变量遮蔽类中的变量。

从实例中访问类属性必须要谨慎。

和通常python变量一样,任何对实例属性的赋值都会创建一个实例属性(如果实例属性不存在的话),并且对其赋值。

但是,如果类属性中存在同名的属性,就是产生前面所说的有趣的副作用。

python3.x依旧存在这个情况,下面上代码:

classFoo:

x =10

f = Foo()

print("原始数据 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))

f.x = f.x+10

print("f.x增加10后 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))

delf.x

print("del干掉f.x后 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))

# 说明

# 代码创建了一个f.x新的实例属性,它覆盖了对类属性的引用

# 然而, 类属性本身没有受到影响, 仍然存在类域中,还可以通过类属性来访问到

# 给一个与类属性同名的实例属性赋值,我们会有效的遮蔽类属性

# 一旦我们删除了这个实例属性,类属性又重现天日.

结果:

原始数据 通过实例访问:10,通过类访问:10

f.x增加10后 通过实例访问:20,通过类访问:10

del干掉f.x后 通过实例访问:10,通过类访问:10

classFoo:

x = {"k1":10}

f = Foo()

print("原始数据 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))

f.x["k1"] =20

print("f.x值变20后 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))

delf.x

print("del干掉f.x后 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))

结果:

Traceback (most recent call last):

AttributeError: x

原始数据 通过实例访问:{'k1':10}, 通过类访问:{'k1':10}

f.x值变20后 通过实例访问:{'k1':20}, 通过类访问:{'k1':20}

为什么下面的dict类型的就会del报错呢??

原因在于:

Python是由C写成的CPython。

C语言中,并没有字符串这个概念:C中叫做字符数组,存储在内存中,是一块连续的空间,不可修改,任何修改字符数组的行为,都会在不影响原始的字符数组下,创建产生一个新的字符数组。

而dict就不一样了,它在内存中存储,是一系列非连续的内存空间,可以在原来的基础上修改,所以,第二个例子中del f.x就会报错。

推荐↓↓↓

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181219B19BXG00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券