靠默契保证的私有制:Python 中的私有

开发 开发工具
在大部分面向对象的编程语言中,对象可以设置其变量和方法为私有。私有变量和方法只能自己使用,即使其子对象都不能访问。大部分编程语言中的私有制,和现实生活中的私有制一样,也是有强制力保证的。只是这部分强制力来自编程语言本身。

人类文明开化以来,私有制似乎是人类历史的主流在西方国家,“私有财产神圣不可侵犯” 是很多资本主义国家的立国原则之一。在我国,“私有财产不可侵犯” 也是写在宪法中的。在人类社会中,私有制表面由由法律保证,实质上是有法律背后的国家强制力保证。

[[205503]]

试图反映世界万物的编程语言,便也产生了私有的概念。在大部分面向对象的编程语言中,对象可以设置其变量和方法为私有。私有变量和方法只能自己使用,即使其子对象都不能访问。大部分编程语言中的私有制,和现实生活中的私有制一样,也是有强制力保证的。只是这部分强制力来自编程语言本身。比如下面的 Java 代码

  1. public class Person{ 
  2.    private int money = 0 

Java 语言强制地让 money 只能内部访问。但并不是所有编程语言都是这样的,Python 就是其中一朵奇葩。Python 中的私有制是由默契保证的。

Python 中的私有制

我们知道 Python 是一门很随意的编程语言,并没有由语言提供的权限控制机制。虽然 Python 对象中的所有属性都可以被外界访问,但我们可以构造出一个伪私有来,如下面的代码。

  1. class Person: 
  2.     def __init__(self):  
  3.         self.__age = 10 

上面的代码定义了一个 Person 类, 有 __age 表示的年龄属性。神奇的事情发生了:

  1. >> p = Person() 
  2. >> p.__age 
  3. Traceback (most recent call last): 
  4.  File "<stdin>", line 1, in <module> 
  5. AttributeError: Person instance has no attribute '__age' 

Person 的对象中没有年龄属性。噢耶,私有制完成。这个现象的原理简单明了:以 __ 打头并且不以 __ 结尾的属性变量,都会自动更名为 _类名__变量名。比如上面的 __age 实际名字是 _Person__age。如果外界不认这个私有,直接访问 _Person_age 是可以破坏这个私有制的。所以这个私有制是建立在开发者之间的默契的基础上:“你既然这么设计了,说明这个变量你不希望我访问或者修改,那我就不访问或者修改了”,并不是建立在强制力的基础上。

访问权限控制

私有制的一个大用处就是控制访问,让一些变量可读不可写。比如写成下面那样,我们就可以通过 age() 访问年龄属性了。

  1. class Person: 
  2.     def __init__(self):  
  3.        self.__age = 10 
  4.     def age(self): 
  5.        return self.__age 

对于 Python 可读不可写变量,我们需要注意有两点和其他语言不一样。***点是 Python 提供了 property 修饰符,可以让函数看起了像变量,但***不用。这是因为看起来像变量,不是很熟悉内部机制的开发者很容易去改动它,比如下面的例子。

  1. class Person: 
  2.     def __init__(self):  
  3.        self.__age = 10 
  4.     @property 
  5.     def age(self): 
  6.        return self.__age 
  7.  
  8. >> p = Person() 
  9. >> p.age 
  10. 10 
  11. >> p.age = 25 
  12. >> p._Person__age 
  13. 10 
  14. >> p.age 
  15. 25 

p.age = 25 是构建了一个新变量 age = 25, 原来的 .age 就不见了。这时候虽然实际的年龄属性 _Person__age 并没有被改变,但程序通过 .age 访问不到它了。

第二点是需要注意聚合类型的属性变量。聚合类型变量中的 list, set 和 dict 中的元素可变。如果一个对象的属性变量是这些聚合类型,那么可以通过修改其元素的方式改变其内容,如下所示。

  1. class Person: 
  2.     def __init__(self):  
  3.        self.__lessons = ["Chinese","English","Math"] 
  4.     
  5.     def lessons(self): 
  6.        return self.__lessons 
  7.  
  8. >> p = Person() 
  9. >> p.lessons 
  10. ["Chinese","English","Math"] 
  11. >> p.lessons[0] = "CS" 
  12. >> p.lessons 
  13. ["CS","English","Math"] 

解决这个问题的办法就是用 tuple, fronzenset 和 fronzendict。

  1. class Person: 
  2.     def __init__(self):  
  3.        self.__lessons = ["Chinese","English","Math"] 
  4.     
  5.     def lessons(self): 
  6.        return tuple(self.__lessons) 

RoomAI 的例子

最近在开发非***信息游戏 AI 环境:RoomAI (点击原文可以查看 RoomAI)。RoomAI 的目标是提供一些非***信息游戏环境和一些基线模型算法,方便 AI 开发人员快速地构建、测试和对比自己的非***游戏 AI 算法。目前 RoomAI 已经支持德州、梭哈和七鬼。RoomAI 的基本流程如下所示:玩家 AI 获得游戏环境给出的信息,当前玩家 AI 选择合适的动作,游戏环境根据该动作推进游戏逻辑;重复上述过程,直到分出胜负。给玩家 AI 的信息必须进行访问权限控制,那么玩家 AI 有可能通过信息获取游戏秘密或者操纵游戏。

为了实现这个目的,之前的做法是深度拷贝游戏环境给出的信息。了解了 Python 私有和访问权限控制,我们很容易想到用这套机制改造之。改造之后,我们通过 RoomAI 中 5 个 AI 对战 10000 局七鬼游戏实验,对比拷贝方法和访问控制方法的效率。

其中原始 copy 是直接使用 copy.deepcopy 进行拷贝,改进拷贝是自己实现了 __ deepcopy __ 函数,访问控制则是使用私有变量从而使得信息可读不可写。很明显地,访问控制方法效率比拷贝方法的高不少。

总结

试图反映世界万物的编程语言也有私有的概念。在大部分面向对象的编程语言中,对象可以设置其变量和方法为私有。私有变量和方法只能自己使用,即使其子对象都不能访问。大部分编程语言中的私有制,和现实生活中的私有制一样,也是有强制力保证的。只是这部分强制力来自编程语言本身。但并不是所有编程语言都是这样的,Python 就是其中一朵奇葩。Python 中的私有制是由默契保证的。私有制的作用之一就是访问控制,可以使得某些属性可读不可写。我们将这个做法用到非***信息游戏 AI 环境 RoomAI 中,提供了运行的效率。

【本文为51CTO专栏作者“李立”的原创稿件,转载请通过51CTO获取联系和授权】

戳这里,看该作者更多好文

责任编辑:赵宁宁 来源: 51CTO专栏
相关推荐

2013-10-16 14:36:55

网络私有制

2013-10-09 15:43:49

云平台私有制网络

2015-12-29 10:10:04

私有云虚拟化公共云

2012-11-01 13:53:23

公有云私有云阿里云

2022-03-17 08:30:28

Python私有属性私有方法

2011-09-29 09:48:39

私有云PaaS云计算

2012-03-27 14:25:23

私有云PaaS云计算

2011-09-15 09:31:32

云计算PaaS私有云

2012-07-31 16:34:46

私有云公有云

2023-09-16 19:38:17

Python私有属性私有方法

2020-04-21 10:42:23

私有云多云云迁移

2018-09-10 15:21:17

私有云裸金属

2015-05-28 13:42:08

2010-06-03 16:09:23

Ubuntu私有驱动

2018-08-27 16:10:49

2013-11-29 11:13:04

电视智能家居多屏互动

2020-06-05 09:38:33

云计算私有云互联网

2009-06-30 19:12:16

云计算SOAIT

2014-11-28 12:58:36

云服务私有云混合云

2011-11-02 09:36:51

私有云云计算
点赞
收藏

51CTO技术栈公众号