浅谈python对象数据的读写权限

 更新时间:2016年09月12日 09:19:00   投稿:jingxian  
下面小编就为大家带来一篇浅谈python对象数据的读写权限。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

面向对象的编程语言在写大型程序的的时候,往往比面向过程的语言用起来更方便,安全。其中原因之一在于:类机制。

类,对众多的数据进行分类,封装,让一个数据对象成为一个完整的个体,贴近现实生活,高度抽象化。但是,python对类的封装并不好,因为所有的属性和方法都是公开的,你可以随意访问或者写入,你可以在类的外部对类的属性进行修改,甚至添加属性。这的确让人感到不安。

下面就来总结一下学习后的解决方案。

1,使用2个下划线前缀隐藏属性或者方法。

__xxx

#!/usr/bin/python3
#-*- coding:utf-8 -*-


class Student:
  def __init__(self,name,score):
    self.name = name
    self.__score = score #将score隐藏起来,使之仅在类内部可用。

  def __show(self):    #一个隐藏的方法,同样只在内部可用
    print(self.name,self.__score)#使用被隐藏的属性__score
    
  def Show(self):
    self.__show()    #注意被隐藏方法的调用方式。


  
def main():
  he = Student('Bob',95)
  he.Show()       #显示:Bob 95
  #print(he.__score)   #AttributeError: 'Student' object has no attribute '__score'
  #he.__show()      #AttributeError: 'Student' object has no attribute '__show'

  #隐藏属性真的被隐藏了吗?其实仍然可使用,使用格式 obj._className__attributeName
  #但是仅仅作为了解,不建议使用隐藏属性。
  print(he._Student__show())  #显示:Bob 95
  print(he._Student__score)   # 显示: 95
  
  
  

if __name__=="__main__":
  main()

双下划线对类属性的影响:

1. 使属性只用于本类的内部,外部以及子类都不可直接读取修改。

2. 使用 _ _ 的类的属性,在实现时会被更改名称,如类中的__age   最后会变为_A__age (名称重整),这个好处是:通常用于涉及到继承的父类中使用。这样避免被子类属性覆盖。

2.创建可管理的属性。

有时候我们需要对属性的写入做额外的检查,对不合法的值拒绝写入,引发异常。

#!/usr/bin/python3
#-*- coding:utf-8 -*-


class Student:
  def __init__(self,name,score):
    self.name = name
    self.score = score 

  @property        #实现属性的读取方法,读取实例的score值时,就会调用这个函数
  def score(self):
    return self.__score

  
  @score.setter     #实现属性写入方法,写入实例的score属性时,调用这个函数
  def score(self,newVal):
    if not isinstance(newVal,(int,float)):
      raise TypeError('score value must be a number')
    if newVal>100 or newVal<0:
      raise ValueError('score value must between 0 and 100')

    self.__score = newVal

  

  
def main():
  he = Student('Bob',95)
  he.score = 100   #重新写入 

  
  print(he.score)  #读取   
    
  

if __name__=="__main__":
  main()

我们可以发现:  self.__score是 属性值 的真正存储的地方,而self.score是函数(只不过它用起来像一个属性),它是获取和写入属性值的方法。

初始化的时候也会调用socre.setter 装饰的函数,因为__init__()函数下出现了self.score的调用

既然self.__score仅仅用来引用属性的值,可不可以用别的命名呢?如saveScore....当然是可以的,但是,它“暴露”了,我们不想让它在外部可用,还是应该

加 __ 将它隐藏,防止意外修改。

有时候,你确定某个类不会涉及到继承,那么,就可以将上述的双下划线改写为单下滑线,虽然不会达到隐藏的作用,但是:一方面,这样不会引发名称重整机制,

避免小题大做,另一面,用一个下划线开头,可以提醒使用者,这个属性不应该直接使用。那么,这就靠自觉了。

一个实例对象可以在外部随意添加属性。

#!/usr/bin/python3
#-*- coding:utf-8 -*-


class Student:
  def __init__(self,name,score):
    self.name = name
    self.score = score 

 

  
def main():
  he = Student('Bob',95)
  he.age = 19
  print(he.age)
  

if __name__=="__main__":
  main()

使用__slots__



#!/usr/bin/python3
#-*- coding:utf-8 -*-


class Student:
  __slots__ = ('name','score') #将属性名以字符串形式加入元组
  def __init__(self,name,score):
    self.name = name
    self.score = score 

 

  
def main():
  he = Student('Bob',95)
  he.age = 19  #AttributeError: 'Student' object has no attribute 'age'
  print(he.age)
  

if __name__=="__main__":
  main()

这样,对象的属性就限定在类的内部了。

但是__slots__不能被继承。而且,__slots__的设计本意并不是上面的用法,而是创建大量(万计)对象时对内存占用进行优化。

总结:

写着写着,我发觉上面的技巧意义不大。类的设计是程序员本人,使用者也是本人,那么,对象属性的

读和写就应该自己把握,类设计时本身不需要太多的保护代码,否则会很臃肿,而且效率降低。保护措施应该发生在类的外部,让类对象接受到的数据永远是合法的,这样会更加轻巧灵活。这是我的感受。

以上这篇浅谈python对象数据的读写权限就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Python 中包/模块的 `import` 操作代码

    Python 中包/模块的 `import` 操作代码

    这篇文章主要介绍了Python 中包/模块的 `import` 操作代码,非常不错,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-04-04
  • 使用tensorflow保存和恢复模型saver.restore

    使用tensorflow保存和恢复模型saver.restore

    这篇文章主要介绍了使用tensorflow保存和恢复模型saver.restore方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • 夯实基础Python列表的索引和切片使用示例

    夯实基础Python列表的索引和切片使用示例

    这篇文章主要为大家介绍了Python列表的索引和切片使用示例基础详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • scrapy框架中的items文件夹的用法详解

    scrapy框架中的items文件夹的用法详解

    这篇文章主要介绍了scrapy框架中的items文件夹的用法详解,在Scrapy框架中,items文件夹是用来存放定义数据模型的Item类的地方,Item类描述了要从网页中提取的数据的结构和字段,通过使用Item类,我们可以更方便地组织和处理爬取到的数据,需要的朋友可以参考下
    2023-10-10
  • Python + selenium 自动化测试框架详解

    Python + selenium 自动化测试框架详解

    这篇文章主要为大家介绍了Python + selenium 自动化测试框架,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • Python Flask中Cookie和Session区别详解

    Python Flask中Cookie和Session区别详解

    Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能,Flask中Cookie和Session有什么区别呢
    2022-07-07
  • python标准库os库的函数介绍

    python标准库os库的函数介绍

    这篇文章主要介绍了python标准库os库的函数介绍,需要的朋友可以参考下
    2020-02-02
  • Python3.6 之后字典是有序的?

    Python3.6 之后字典是有序的?

    字典数据是有序的, 但是这个序不是由外部控制, 而是内部字典定位机制的序 所以对外来讲, 数据本身是无序的 你每次遍历的顺序一样, 是因为枚举结果是按内部排序输出 而无序则表示在你无法从外部控制最终的输出顺序,下面我们来学习Python字典有序性的相关资料又当怎样吧
    2021-12-12
  • python服务器中发送外部请求的基本步骤

    python服务器中发送外部请求的基本步骤

    在Python中,服务器发送外部请求是一个常见的操作,尤其是在需要集成不同服务或API时,有多种库可以帮助你完成这项任务,但最流行和广泛使用的库之一是requests,下面给大家分享python服务器中发送外部请求的基本步骤,感兴趣的朋友一起看看吧
    2024-08-08
  • python 标准差计算的实现(std)

    python 标准差计算的实现(std)

    这篇文章主要介绍了python 标准差计算的实现(std),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07

最新评论