Python变量访问权限控制的几种方法:单下划线、双下划线、__slots__、@property、__all__

本文介绍了Python中控制变量访问权限的五种方法:1) 单下划线避免`from module import *`导入;2) 双下划线实现类内部保护成员,外部通过`_classname__XXX`间接访问;3) `__slots__`节省内存并限制实例属性;4) `@property`装饰器将方法转化为只读属性;5) `__all__`控制`import *`导出的模块成员。

1.单下划线:

单下划线命名的变量(包括类,函数,普通变量)不能通过from module import *导入到另外一个模块中。

testA.py

# testA.py
class _Foo(object):
    def fun(self):
        print('fun in class _Foo')
        
        
def _bar(a):
    print(a)
    

_foobar = 100 

testB.py

from testA import *

a = _Foo()
_bar('hello world')
c = _foobar
testB.py会报错:

Traceback (most recent call last):
  File "E:/Code/python3/EffectivePython/test2.py", line 4, in <module>
    a = _Foo()
NameError: name '_Foo' is not defined

2.双下划线:

Python中没有private之类的关键字来控制类成员访问权限的变量,但是可以通过把变量命名为双下划线来达到同样的效果,形式为__XXX(不是__XXX__,这个形式有特殊含义,是可以访问的)。

>>> class Foo(object):
	def __init__(self, a):
		self.__a = a
	def __fun(self):
		print(self.__a)

		
>>> t = Foo(100)
>>> t.__fun()
Traceback (most recent call last):
  File "<pyshell#25>", line 1, in <module>
    t.__fun()
AttributeError: 'Foo' object has no attribute '__fun'
>>> t.__a
Traceback (most recent call last):
  File "<pyshell#26>", line 1, in <module>
    t.__a
AttributeError: 'Foo' object has no attribute '__a'
>>>

类本身可以访问__XXX变量,但是在其它作用域不行。原理就是在Python中类的__XXX形式的变量变量会被重整为_classname__XXX,所以不能访问__XXX形式的变量。
其实还是可以通过_classname__XXX来访问,不过不建议,代码如下:

>>> class Foo(object):
	def __init__(self, a):
		self.__a = a
	def __fun(self):
		print(self.__a)

		
>>> t = Foo(100)
>>> t._Foo__a
100
>>> 

3. __slots__:

__slots__可以控制类成员变量的增加,只有出现在__slots__中的变量才可以增加到类中。
>>> class Foo():
	__slots__ = ('name', 'age')
	def __init__(self, a, b):
		self.name = a
		self.age = 19
		self.addr = 'China'


>>> t = Foo('xmr', 18)
Traceback (most recent call last):
  File "<pyshell#68>", line 1, in <module>
    t = Foo('xmr', 18)
  File "<pyshell#67>", line 6, in __init__
    self.addr = 1000
AttributeError: 'Foo' object has no attribute 'addr'
>>>
>>> class Bar():
	__slots__ = ('name', 'age')
	def __init__(self, a, b):
		self.name = a
		self.age = 19


		
>>> t = Bar('xmr', 18)
>>> t.name = 'xmr'
>>> t.age = 19
>>> t.addr = 'China'
Traceback (most recent call last):
  File "<pyshell#76>", line 1, in <module>
    t.addr = 'China'
AttributeError: 'Bar' object has no attribute 'addr'
>>>
上面的代码中类Foo和Bar都不能增加除了name和age外的其它成员变量,因为__slots__中只有name个age。

4.@property:

@property的作用是把成员函数当变量用,但是该变量不能被修改:

>>> a = Foo(100)
>>> a.fun
100
>>> a.fun = 101
Traceback (most recent call last):
  File "<pyshell#97>", line 1, in <module>
    a.fun = 101
AttributeError: can't set attribute
>>> 

5.__all__:

未完继续。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值