Getter 和 setter在java中被广泛使用。一个好的java编程准则为:将所有属性设置为私有的,同时为属性写getter和setter函数以供外部使用。 这样做的好处是属性的具体实现被隐藏,当未来需要修改时,只需要修改getter 和 setter即可,而不用修改代码中所有引用这个属性的地方。可能做的修改为:

  • 在获取或设置属性时打一条日志
  • 设置属性时,对值对进检查
  • 设置发生时, 修改设置的值
  • 获取属性时,动态地计算值

可谓是好处多多,getter和setter为变量访问提供了灵活的方式。

但python中情况却不同,因为对象属性访问的机制不同。java中需要为变量写getter和setter的原因为:当我们写这样的表达式 person.name 来获取一个 person 对象的 name 属性时,这个表达式的意义是固定的,它就是获取这个属性,而不可能触发一个函数的调用。但对于python, 这个表达式即可能是直接获取一个属性,也可能会调用一个函数。这取决 Person 类的实现方式。也就是说,python的对象属性访问的语法,天然就提供了getter和setter的功能。

由于这个区别,我们没有必要在python中为每个对象的属性写getter和setter。最开始时,我们总是将属性作为一个直接可访问的属性。当后续需要对这个属性的访问进行一些控制时,我们可以将其修改为函数触发式属性。在修改前后,调用这个对象属性的代码不用修改,因为还是使用相同的语法来访问这个属性。

可以使用@property 装饰器将一个直接访问的属性转变为函数触发式属性。如下所示,使用@property前的代码为

class Person:
def __init__(self, name):
self.name = name person = Person("Tom")
print(person.name)

代码的输出为:

Tom

此时为直接访问 name 这个属性。当我们需要确保 name 是一个字符串时,可以使用 @property 装饰器将属性转变为一个函数调用,如下所示。

class Person:
def __init__(self, name):
self.name = name @property
def name(self):
print("get name called")
return self._name @name.setter
def name(self, name):
print("set name called")
if not isinstance(name, str):
raise TypeError("Expected a string")
self._name = name person = Person("Tom")
print(person.name)

代码的输出为:

set name called
get name called
Tom

可以看出

  • 在创建Person对象时(代码的倒数第二行), 用于set name的函数被调用。这个函数会检查输入是否为一个字符串,如不是则raise一个TypeError
  • 在获取属性时(代码的最后一行),用于get name的函数被调用
  • 在修改前后,使用Person类的代码完全相同

总结

Python中对象访问的语法即可能是直接访问这个属性,也可能是调用一个函数,这取决于类的实现方式。我们可以在不修改调用者代码的前提下,轻松切换这两种方式。可见python原生就提供了添加额外getter和setter所带来的好处。因此没有必要一开始就为对象属性编写getter和setter函数,而是在需要时切换到函数调用式属性。

 

为什么不需要为Python对象添加 getter 和 setter的更多相关文章

  1. 【02】对象的Getter and Setter

    java和C#非常相似,它们大部分的语法是一样的,但尽管如此,也有一些地方是不同的. 为了更好地学习java或C#,有必要分清它们两者到底在哪里不同. 我们这次要来探讨对象的Getter and Se ...

  2. 对象存取器属性:getter和setter

    在一个对象中,操作其中的属性或方法,通常运用最多的就是读(引用)和写了,譬如说o.a,这就是一个读的操作,而o.b = 1则是一个写的操作.事实上在除ie外最新主流浏览器的实现中,任何一个对象的键值都 ...

  3. [转载]Python使用@property装饰器--getter和setter方法变成属性

    原贴:为什么Python不需要getter和setter getter 和 setter在java中被广泛使用.一个好的java编程准则为:将所有属性设置为私有的,同时为属性写getter和sette ...

  4. JavaScript getter和setter

    对象的属性是由属性名name,值key,和其他特性(可读写性 writable,可枚举性enumerable,可配置性configurable)组成的.从ES5开发,提供了getter和setter ...

  5. 为什么要设置getter和setter?

    面向对象语言中,通常把属性设置为私有,然后添加getter和setter方法来访问.有人说,这本质上和设置属性为公有没有区别,干脆把属性public算了.也有人反驳,这样做破坏了封装.但是,破坏了封装 ...

  6. 给内置对象或自定义对象添加存取器属性(getter setter)的方法总结

    funct = { get: function() { return this._x }, set: function(value) { this._x = value } } function Ob ...

  7. Python如何动态的为对象添加方法或属性,__slots__用法

    代码示例如下: import types    #使用MethodType方法需要导入包 class test(object):  #定义 一个test类,包含name属性和f()方法 def __i ...

  8. Python对象(译)

    这是一篇我翻译的文章,确实觉得原文写的非常好,简洁清晰 原文链接:http://effbot.org/zone/python-objects.htm ------------------------- ...

  9. @property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的

    出题者简介: 孙源(sunnyxx),目前就职于百度 整理者简介:陈奕龙(子循),目前就职于滴滴出行. 转载者:豆电雨(starain)微信:doudianyu @property 的本质是什么? @ ...

随机推荐

  1. 逻辑卷管理lvm

    逻辑卷管理LVM 一 创建逻辑卷 1准备分区或硬盘 这里使用/dev/sdb./dev/sdc两块硬盘和/dev/sda9./dev/sda10两个分区,大小都为1G,磁盘有限,我也不想这么抠的. 添 ...

  2. Dubbo源码分析系列---扩展点加载

    扩展点配置: 约定: 在扩展类的jar包内,放置扩展点配置文件:META-INF/dubbo/接口全限定名,内容为:配置名=扩展实现类全限定名,多个实现类用换行符分隔.(摘自dubbo文档) 示例: ...

  3. javacv开发详解之1:调用本机摄像头视频(建议使用javaCV1.3版本)

    javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...

  4. 【论文:麦克风阵列增强】Microphone Array Post-Filtering For Non-Stationary Noise Suppression

    作者:桂. 时间:2017-06-08  08:01:41 链接:http://www.cnblogs.com/xingshansi/p/6957027.html 原文链接:http://pan.ba ...

  5. 初学vitmio,vitmio的环境配置及遇到的坑

    1 到官网或者github下载vitamio 官网地址:https://www.vitamio.org/ github地址:https://github.com/yixia/VitamioBundle ...

  6. 原生和jQuery的ajax用法

    jQuery的ajax方法: $.ajax({ url:'/comm/test1.php', type:'POST', //GET async:true, //或false,是否异步 data:{ n ...

  7. 基于android的语音识别

    1.注册账户,添加应用 2.针对android平台的选择应用,下载SDK 3.将SDK的libs下文件拷贝到工程的libs目录下 4.添加用户权限 <uses-permission androi ...

  8. C# 调用cmd.exe的方法

    网上有很多用C#调用cmd的方法,大致如下: [c-sharp] view plaincopy private void ExecuteCmd(string command)   {   Proces ...

  9. thinkphp获取特定字段的两种方法

    thinkphp getField( )和field( ) 2014年10月05日 ⁄ 综合 ⁄ 共 1509字 ⁄ 字号 小 中 大 ⁄ 评论关闭 做数据库查询的时候,比较经常用到这两个,总是查手册 ...

  10. android的drawable资源

    1.android中可以通过xml文件配置资源,比如字符串啦,整数拉.浮点数等等,当然也可以配置图片资源和选择器,下面我们就看看几种图片资源的配置. @1矩形方框,带渐变色的配置代码 <?xml ...