Python/Article/PythonBasis/python8/9.md

119 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 九、类的访问控制 #
## 1、类属性的访问控制 ##
在 Java 中,有 public (公共)属性 和 private (私有)属性,这可以对属性进行访问控制。
那么在 Python 中有没有属性的访问控制呢?
一般情况下,我们会使用 `__private_attrs` 两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 `self.__private_attrs`
为什么只能说一般情况下呢?
因为实际上, Python 中是没有提供私有属性等功能的。
但是 Python 对属性的访问控制是靠程序员自觉的。为什么这么说呢?
看看下面的示例:
![](http://twowaterimage.oss-cn-beijing.aliyuncs.com/2019-10-09-Python%20%E5%B1%9E%E6%80%A7%E8%AE%BF%E9%97%AE%E6%8E%A7%E5%88%B6.png)
仔细看图片,为什么说双下划线不是真正的私有属性呢?我们看下下面的例子,用下面的例子来验证:
```python
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
class UserInfo(object):
def __init__(self, name, age, account):
self.name = name
self._age = age
self.__account = account
def get_account(self):
return self.__account
if __name__ == '__main__':
userInfo = UserInfo('两点水', 23, 347073565);
# 打印所有属性
print(dir(userInfo))
# 打印构造函数中的属性
print(userInfo.__dict__)
print(userInfo.get_account())
# 用于验证双下划线是否是真正的私有属性
print(userInfo._UserInfo__account)
```
输出的结果如下图:
![](http://twowaterimage.oss-cn-beijing.aliyuncs.com/2019-10-09-Python%E5%8F%8C%E4%B8%8B%E5%88%92%E7%BA%BF%E5%B1%9E%E6%80%A7.png)
## 2、类专有的方法 ##
一个类创建的时候,就会包含一些方法,主要有以下方法:
类的专有方法:
| 方法 | 说明 |
| ------| ------ |
|`__init__` |构造函数,在生成对象时调用|
|`__del__ `| 析构函数,释放对象时使用|
|`__repr__ `| 打印,转换|
|`__setitem__ `| 按照索引赋值|
|`__getitem__`| 按照索引获取值|
|`__len__`| 获得长度|
|`__cmp__`| 比较运算|
|`__call__`| 函数调用|
|`__add__`| 加运算|
|`__sub__`| 减运算|
|`__mul__`|乘运算|
|`__div__`| 除运算|
|`__mod__`| 求余运算|
|`__pow__`|乘方|
当然有些时候我们需要获取类的相关信息,我们可以使用如下的方法:
* `type(obj)`:来获取对象的相应类型;
* `isinstance(obj, type)`:判断对象是否为指定的 type 类型的实例;
* `hasattr(obj, attr)`:判断对象是否具有指定属性/方法;
* `getattr(obj, attr[, default])` 获取属性/方法的值, 要是没有对应的属性则返回 default 值(前提是设置了 default否则会抛出 AttributeError 异常;
* `setattr(obj, attr, value)`:设定该属性/方法的值,类似于 obj.attr=value
* `dir(obj)`:可以获取相应对象的所有属性和方法名的列表:
## 3、方法的访问控制 ##
其实我们也可以把方法看成是类的属性的,那么方法的访问控制也是跟属性是一样的,也是没有实质上的私有方法。一切都是靠程序员自觉遵守 Python 的编程规范。
示例如下,具体规则也是跟属性一样的,
```python
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
class User(object):
def upgrade(self):
pass
def _buy_equipment(self):
pass
def __pk(self):
pass
```