python 类成员可见性
类似于java的语言,python也有自己的访问权限控制。面向对象的很大一部分也就在于对代码访问的在控制。本文在学习python对访问控制的学习。
class TestIsVisible(object):
def __init__(self, visible, invisible, non_know):
self.visible = visible
self.__invisible = invisible
self._visible = non_know
def hello_world(self):
dic = dict()
dic["hello"] = "world!"
print dic
def __hello_china(self):
dic = dict()
dic["hello"] = "china"
print dic
if __name__ == '__main__':
visible_object = TestIsVisible("can see", "can not see", "non know if visible")
print visible_object.visible
print visible_object._visible
print visible_object.__dict__
print dir(visible_object)
print visible_object.__invisible
结果如下:
can see
non know if visible
{'hello': 'world!'}
{'visible': 'can see', '_TestIsVisible__invisible': 'can not see', '_visible': 'non know if visible'}
['_TestIsVisible__hello_china', '_TestIsVisible__invisible', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_visible', 'hello_world', 'visible']
Traceback (most recent call last):
File "/Users/guifeng.chen/program/testdj/learn_super.py", line 139, in <module>
print visible_object.__invisible
AttributeError: 'TestIsVisible' object has no attribute '__invisible'
- 由此可见 python通过命名的起始处下划线来区分是private变量,protect变量还是public变量。
权限名称 | 权限控制 | 起始标志 |
---|---|---|
public | 可见 外部可以访问 | 无 _ |
protect | 不可见 外部可以访问 | _(单下划线) |
private | 不可见 不可访问 | __ (双下划线) |
dict
__dict__ : 类的属性(包含一个字典,由类的数据属性组成)
如以上的打印中
{'visible': 'can see', '_TestIsVisible__invisible': 'can not see', '_visible': 'non know if visible'}
就像相关的数据属性字典。
这里需要注意的是 _TestIsVisible__invisible 这一项。这就解释了为什么通过
visible_object.__invisible
这种方式访问不了。因为名字被改了嘛
那么我们试想一下可以怎么访问?
- 直接在全局命名中找?
print _TestIsVisible__invisible
- 在相关的对象空间中
visible_object._TestIsVisible__invisible
是的,通过第二种方式可以访问到变量
print visible_object._TestIsVisible__invisible
visible_object._TestIsVisible__invisible = "change the invisible value"
print visible_object._TestIsVisible__invisible
print visible_object.__dict__
甚至我们可以直接改变它的值,一下为输出
can not see
change the invisible value
{'visible': 'can see', '_TestIsVisible__invisible': 'change the invisible value', '_visible': 'non know if visible'}
这也是在无意间发现的一个trick吧。
dict 方法
print type(visible_object.__dict__)
<type 'dict'>
网上别的地方有关于dict的介绍,使用update的方法之类的。感觉这个就比较扯淡。它拥有的方法其实是因为它是dict类型。只要把它当成dict就好了。
dir
dir 是针对象而言,查看它所有用的方法,属性。然而对python而言一切都是对象。
通过 help 命令查看dir功能。
Help on built-in function dir in module __builtin__:
dir(...)
dir([object]) -> list of strings
If called without an argument, return the names in the current scope.
Else, return an alphabetized list of names comprising (some of) the attributes
of the given object, and of attributes reachable from it.
If the object supplies a method named __dir__, it will be used; otherwise
the default dir() logic is used and returns:
for a module object: the module's attributes.
for a class object: its attributes, and recursively the attributes
of its bases.
for any other object: its attributes, its class's attributes, and
recursively the attributes of its class's base classes.
可以的知道
- 没有参数 dir() 返回当前作用域可见的类 函数 属性 变量等 以字符串返回
- 如果有传入对象,那么先看有没有实现 dir 方法,如果有则调用dir.否则
- - 对module来说 返回其 attribute
- - 对class 来说,返回其 attribute 并且递归其父类。
- - 对于其他的类组装也是不停递归到其根。
对于当前的代码执行
print dir()
print dir(visible_object)
得到
['Animal', 'Dog', 'LOGISTIC_CHANNEL_CLASS_LIST', 'Logistics', 'TestIsVisible', 'VN_LOGISTIC_TOKEN', 'VnHTTPManager', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'crypt', 'dog', 'get_distance', 'get_price', 'json', 'learn_decode', 'math', 'register_logistic_class', 'rules', 'shipping_fee', 'sys', 'visible_object']
['_TestIsVisible__hello_china', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'ddd', 'hello_world', 'sss']
有些多余是因为本文件包含了别的一切类测试数据,