Python Properties vs. Getters and Setters

属性

基于数据封装的原则,Getters和setters在许多面像对象的语言中广泛使用。

数据封装可看作是将数据和某些操作他们的方法进行捆绑。这些方法就是获取数据的getter方法,和更新数据的setter方法。基于这一原则,类的属性就会被设置为私有,和其它的代码进行分开而进行隐藏和保护。

 

不幸的是,大家普遍认为,一个合适的Python类应该使用getters和setters来封装一些私有属性。当程序员引入一个新的属性时,则可以设置它为私有属性并自动为其生成getter和setter。这些程序员通常会用编辑器和IDE,而达到这一个目的。这些工具甚至为提醒用户,新属性是否公开,因为Pythonic way就是引入一个属性,设置为公开属性。这是Java程序员不敢想象的。

让我们来看下Javaesque way的getters和setters来封装私有变量self.__x

class P:
  
  def __init__(self,x):
    self.__x = x
 
  def get_x(self):
    return self.x

  def set_x(self, x)
    self.__x = x

保存为p.y,则执行结果为:

 

让我们按照Pythonic way重写该文件

class P:

  def __init__(self,x):
    self.x = x

没有getter, setter,也没有私有变量self.__x。 Pythonice way, 我们用了公开变量。

 

执行结果如下:

Jave程序员们大喊“这里没有数据封装”。是的,这种情况下,是没有数据封装,是因为在我们这个案例中不需要,毕竟在第一个案例中的get_x和set_x也仅仅是获取数据。让我们设想以下复杂的情形,假设x的有效值范围为[0,1000]。如果输入值大于1000,x为1000,对应的,如果输入数值小于0,则为0,则在第一种方法里很容易实现。如下:

class P:
    def __init__(self,x):
        self.__x = x

    def get_x(self):
        return self.__x

    def set_x(self, x):
        if x > 1000:
            x = 1000
        if x < 0:
            x = 0

        self.__x = x

则输出为:

则在第二种方式里,则没有办法实现。

Python针对这个问题提供了一个叫“properties”解决方案,如下:

class P:
    def __init__(self, x):
        self.ourX = x

    @property
    def ourX(self):
        return self.__ourX

    @ourX.setter
    def ourX(self, val):
        if val < 0:
            self.__ourX = 0
        elif val > 1000:
            self.__ourX = 1000
        else:
            self.__ourX = val

获取值的方法x被装饰为@property,对应的需有一个作为setter的函数ourX被装饰成@ourX.setter。

这里还需要声明2件事:

1,我们在__init__的方法中,写入“self.ourX = x”。"property"该ourX。

2,我们用同一个方法名定义了两个方法 "def x(self)" 和“def x(self,x)”。通常,这样定义函数,是会报错的。用装饰器装饰方可。

则执行结果为:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值